home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 3 / CD ACTUAL 3.iso / linux / system / bsvc-1.000 / bsvc-1 / bsvc-1.0.4 / src / Sim68000 / cpu / exec.cxx < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-26  |  145.3 KB  |  5,482 lines

  1. //////////////////////////////////////////////////////////////////////////////
  2. // $Id: exec.cxx,v 1.9 1995/07/26 20:30:39 bmott Exp $
  3. //////////////////////////////////////////////////////////////////////////////
  4. // exec.cxx 
  5. //
  6. // Functions to simulate 68000 instruction execution
  7. // 
  8. // Sim68000 "Motorola 68000 Simulator"
  9. // Copyright (c) 1993
  10. // By: Bradford W. Mott
  11. // November 4,1993
  12. //
  13. ///////////////////////////////////////////////////////////////////////////////
  14. // $Log: exec.cxx,v $
  15. // Revision 1.9  1995/07/26  20:30:39  bmott
  16. // ADDA, CMPA, LEA, LINK, SUBA, and UNLK were not accessing the correct
  17. // stack pointer when the processor was in supervisor mode
  18. //
  19. // Revision 1.8  1995/07/03  19:01:38  bmott
  20. // Fixed bug in DIVS instruction that was introduced by the last version.
  21. //
  22. // Revision 1.7  1995/06/29  23:15:16  bmott
  23. // Fixed bug in the DIVS instruction, fixed post-increment and pre-decrement
  24. // bug in the Bit instructions
  25. //
  26. // Revision 1.6  1995/02/18  19:20:00  bmott
  27. // Added code to handle the SUBX instruction, fixed addressing mode bug
  28. // in the CMPM instruction, fixed stack pointer bug in the RTR instruction
  29. //
  30. // Revision 1.5  1995/02/11  03:28:14  bmott
  31. // Fixed condition code bug in the CMP and CMPA instructions
  32. //
  33. // Revision 1.4  1995/01/13  00:33:26  bmott
  34. // Change the in_register argument for the ComputeEffectiveAddress
  35. // member function
  36. //
  37. // Revision 1.3  1995/01/01  05:29:45  bmott
  38. // Fixed bug in the RTS instruction and added code to handle the STOP
  39. // instruction.
  40. //
  41. // Revision 1.2  1994/09/22  00:11:56  bmott
  42. // Added method to execute BREAK instruction
  43. //
  44. // Revision 1.1  1994/02/18  20:04:12  bmott
  45. // Initial revision
  46. //
  47. ///////////////////////////////////////////////////////////////////////////////
  48.  
  49. #include "m68000.hxx"
  50. #include "Tools.hxx"
  51.  
  52. ///////////////////////////////////////////////////////////////////////////////
  53. // Compute the effective address, given the mode and register bits
  54. ///////////////////////////////////////////////////////////////////////////////
  55. int m68000::ComputeEffectiveAddress(unsigned long& address,
  56.                                     int& in_register,
  57.                                     String& description,
  58.                                     int mode_register,
  59.                                     int size, int trace)
  60. {
  61.   unsigned long tmp;
  62.   unsigned int extend_word;
  63.   int status;
  64.  
  65.   switch (mode_register>>3)
  66.   {
  67.     case 0:  // Data Register Direct
  68.       address=(mode_register & 0x7) + D0_INDEX;
  69.       if(trace)
  70.       {
  71.         description+=register_data[address].name;
  72.       }
  73.       in_register=1;
  74.       return(EXECUTE_OK);
  75.       break;
  76.  
  77.     case 1:  // Address Register Direct
  78.       address=(mode_register & 0x7);
  79.       if((address==7) && (register_value[SR_INDEX] & S_FLAG))
  80.         address=SSP_INDEX;
  81.       else
  82.         address+=A0_INDEX;
  83.       if(trace)
  84.       {
  85.         description+=register_data[address].name;
  86.       }
  87.       in_register=1;
  88.       return(EXECUTE_OK);
  89.       break;
  90.  
  91.     case 2:  // Address Register Indirect
  92.       tmp=(mode_register & 0x7);
  93.       if((tmp==7) && (register_value[SR_INDEX] & S_FLAG))
  94.         tmp=SSP_INDEX;
  95.       else
  96.         tmp+=A0_INDEX;
  97.       address=register_value[tmp];
  98.       if(trace)
  99.       {
  100.         description+="(";
  101.         description+=register_data[tmp].name;
  102.         description+=")";
  103.       }
  104.       in_register=0;
  105.       return(EXECUTE_OK);
  106.       break;
  107.        
  108.     case 3:  // Address Register Indirect with Post-Increment
  109.       tmp=(mode_register & 0x7);
  110.       if((tmp==7) && (register_value[SR_INDEX] & S_FLAG))
  111.         tmp=SSP_INDEX;
  112.       else
  113.         tmp+=A0_INDEX;
  114.       address=register_value[tmp];
  115.       switch (size)
  116.       {
  117.         case BYTE:
  118.           register_value[tmp]+=1;
  119.           break;
  120.         case WORD:
  121.           register_value[tmp]+=2;
  122.           break;
  123.         case LONG:
  124.           register_value[tmp]+=4;
  125.           break;
  126.       }
  127.       if(trace)
  128.       {
  129.         description+="(";
  130.         description+=register_data[tmp].name;
  131.         description+=")+";
  132.       }
  133.       in_register=0;
  134.       return(EXECUTE_OK);
  135.       break;
  136.  
  137.     case 4:  // Address Register Indirect with Pre-Decrement 
  138.       tmp=(mode_register & 0x7);
  139.       if((tmp==7) && (register_value[SR_INDEX] & S_FLAG))
  140.         tmp=SSP_INDEX;
  141.       else
  142.         tmp+=A0_INDEX;
  143.       switch (size)
  144.       {
  145.         case BYTE:
  146.           register_value[tmp]-=1;
  147.           break;
  148.         case WORD:
  149.           register_value[tmp]-=2;
  150.           break;
  151.         case LONG:
  152.           register_value[tmp]-=4;
  153.           break;
  154.       }
  155.       address=register_value[tmp];
  156.       if(trace)
  157.       {
  158.         description+="-(";
  159.         description+=register_data[tmp].name;
  160.         description+=")";
  161.       }
  162.       in_register=0;
  163.       return(EXECUTE_OK);
  164.       break;
  165.  
  166.     case 5:  // Address Register Indirect with Displacement
  167.       tmp=(mode_register & 0x7);
  168.       if((tmp==7) && (register_value[SR_INDEX] & S_FLAG))
  169.         tmp=SSP_INDEX;
  170.       else
  171.         tmp+=A0_INDEX;
  172.       address=register_value[tmp];
  173.  
  174.       if((status=Peek(register_value[PC_INDEX],extend_word,WORD))!=EXECUTE_OK)
  175.       {
  176.         register_value[PC_INDEX]+=2;
  177.         return(status);
  178.       } 
  179.       else
  180.       {
  181.         register_value[PC_INDEX]+=2;
  182.       } 
  183.  
  184.       address+=SignExtend(extend_word,WORD);
  185.       if(trace)
  186.       {
  187.         description+="($";
  188.         description+=IntToString(extend_word,4);
  189.         description+=",";
  190.         description+=register_data[tmp].name;
  191.         description+=")";
  192.       }
  193.       in_register=0;
  194.       return(EXECUTE_OK);
  195.       break;
  196.  
  197.     case 6:  // Address Register Indirect with Index and 8-bit Displacement
  198.       tmp=(mode_register & 0x7);
  199.       if((tmp==7) && (register_value[SR_INDEX] & S_FLAG))
  200.         tmp=SSP_INDEX;
  201.       else
  202.         tmp+=A0_INDEX;
  203.       address=register_value[tmp];
  204.  
  205.       if((status=Peek(register_value[PC_INDEX],extend_word,WORD))!=EXECUTE_OK)
  206.       {
  207.         register_value[PC_INDEX]+=2;
  208.         return(status);
  209.       } 
  210.       else
  211.       {
  212.         register_value[PC_INDEX]+=2;
  213.       } 
  214.  
  215.       address+=SignExtend(extend_word&0xff,BYTE);     // Add 8-bit displacement
  216.       if(trace)
  217.       {
  218.         description+="$";
  219.         description+=IntToString(extend_word&0xff,2);
  220.         description+="(";
  221.         description+=register_data[tmp].name;
  222.         description+=",";
  223.       }
  224.        
  225.       if(extend_word & 0x8000)                        // Get register number
  226.       {
  227.         tmp=((extend_word >> 12) & 0x7);
  228.         if((tmp==7) && (register_value[SR_INDEX] & S_FLAG))
  229.           tmp=SSP_INDEX;
  230.         else
  231.           tmp+=A0_INDEX;
  232.       }
  233.       else
  234.       {
  235.         tmp=((extend_word >> 12) & 0x7) + D0_INDEX;
  236.       }
  237.  
  238.       if(extend_word & 0x0800)
  239.         address+=register_value[tmp];
  240.       else
  241.         address+=SignExtend(register_value[tmp],WORD);
  242.  
  243.       if(trace)
  244.       {
  245.         description+=register_data[tmp].name;
  246.         if(extend_word & 0x0800)
  247.           description+=".L)";
  248.         else
  249.           description+=".W)";
  250.       }
  251.       in_register=0;
  252.       return(EXECUTE_OK);
  253.       break;
  254.  
  255.     case 7:
  256.       switch (mode_register & 7)
  257.       {
  258.         case 0:  // Absolute Short Address
  259.           if((status=Peek(register_value[PC_INDEX],extend_word,WORD))
  260.               != EXECUTE_OK)
  261.           {
  262.             register_value[PC_INDEX]+=2;
  263.             return(status);
  264.           } 
  265.           else
  266.           {
  267.             register_value[PC_INDEX]+=2;
  268.           } 
  269.           address=SignExtend(extend_word,WORD);
  270.           if(trace)
  271.           {
  272.             description+=IntToString(extend_word,4);
  273.             description+=".W";
  274.           }
  275.           in_register=0;
  276.           return(EXECUTE_OK);
  277.           break;
  278.  
  279.         case 1:  // Absolute Long Address
  280.           if((status=Peek(register_value[PC_INDEX],extend_word,LONG))
  281.               != EXECUTE_OK)
  282.           {
  283.             register_value[PC_INDEX]+=4;
  284.             return(status);
  285.           } 
  286.           else
  287.           {
  288.             register_value[PC_INDEX]+=4;
  289.           } 
  290.           address=extend_word;
  291.           if(trace)
  292.           {
  293.             description+=IntToString(extend_word,8);
  294.             description+=".L";
  295.           }
  296.           in_register=0;
  297.           return(EXECUTE_OK);
  298.           break;
  299.  
  300.         case 2:  // Program Counter with Displacement
  301.           address=register_value[PC_INDEX];
  302.           if((status=Peek(register_value[PC_INDEX],extend_word,WORD))
  303.               != EXECUTE_OK)
  304.           {
  305.             register_value[PC_INDEX]+=2;
  306.             return(status);
  307.           } 
  308.           else
  309.           {
  310.             register_value[PC_INDEX]+=2;
  311.           }
  312.           address+=SignExtend(extend_word,WORD);
  313.           if(trace)
  314.           {
  315.             description+="($";
  316.             description+=IntToString(extend_word,4);
  317.             description+=",PC)";
  318.           }
  319.           in_register=0;
  320.           return(EXECUTE_OK);
  321.           break;
  322.  
  323.         case 3:  // Program Counter with Index and 8-bit Displacement
  324.           address=register_value[PC_INDEX];
  325.           if((status=Peek(register_value[PC_INDEX],extend_word,WORD))
  326.               != EXECUTE_OK)
  327.           {
  328.             register_value[PC_INDEX]+=2;
  329.             return(status);
  330.           } 
  331.           else
  332.           {
  333.             register_value[PC_INDEX]+=2;
  334.           }
  335.  
  336.           address+=SignExtend(extend_word & 0xff,BYTE);  // 8-bit displacement
  337.           if(trace)
  338.           {
  339.             description+="$";
  340.             description+=IntToString(extend_word & 0xff,2);
  341.             description+="(PC,";
  342.           }
  343.  
  344.           if(extend_word & 0x8000)                       // Get register number
  345.           {
  346.             tmp=((extend_word >> 12) & 0x7);
  347.             if((tmp==7) && (register_value[SR_INDEX] & S_FLAG))
  348.               tmp=SSP_INDEX;
  349.             else
  350.               tmp+=A0_INDEX;
  351.           }
  352.           else
  353.           {
  354.             tmp=((extend_word >> 12) & 0x7) + D0_INDEX;
  355.           }
  356.  
  357.           if(extend_word & 0x0800)
  358.             address+=register_value[tmp];
  359.           else
  360.             address+=SignExtend(register_value[tmp],WORD);
  361.  
  362.           if(trace)
  363.           {
  364.             description+=register_data[tmp].name;
  365.             if(extend_word & 0x0800)
  366.               description+=".L)";
  367.             else
  368.               description+=".W)";
  369.           }
  370.           in_register=0;
  371.           return(EXECUTE_OK);
  372.           break;
  373.  
  374.         case 4:  // Immediate Data
  375.           address = register_value[PC_INDEX];
  376.  
  377.           if(size == BYTE)
  378.             ++address;
  379.  
  380.           if((size == BYTE) || (size == WORD))
  381.             register_value[PC_INDEX]+=2;
  382.           else
  383.             register_value[PC_INDEX]+=4;
  384.  
  385.           if(trace)
  386.           {
  387.             // Fetch the immediate data
  388.             if((status=Peek(address, extend_word, size)) != EXECUTE_OK)
  389.               return(status);
  390.  
  391.             description+="#$";
  392.             if(size==BYTE)
  393.               description+=IntToString(extend_word,2);
  394.             else if(size==WORD)
  395.               description+=IntToString(extend_word,4);
  396.             else if(size==LONG)
  397.               description+=IntToString(extend_word,8);
  398.           }
  399.           in_register=0;
  400.           return(EXECUTE_OK);
  401.           break;
  402.       }
  403.   } 
  404.   return(EXECUTE_ILLEGAL_INSTRUCTION);
  405. }
  406.  
  407. ///////////////////////////////////////////////////////////////////////////////
  408. // Sign extend the value
  409. ///////////////////////////////////////////////////////////////////////////////
  410. unsigned int m68000::SignExtend(unsigned int value, int size)
  411. {
  412.   switch (size) 
  413.   {
  414.     case BYTE:
  415.       if(value & 0x80)
  416.         return((value & 0xff) | 0xffffff00);
  417.       else
  418.         return(value & 0xff);
  419.       break;
  420.  
  421.     case WORD:
  422.       if(value & 0x8000)
  423.         return((value & 0xffff) | 0xffff0000);
  424.       else
  425.         return(value & 0xffff);
  426.       break;
  427.  
  428.     default:  // LONG
  429.       return(value & 0xffffffff);
  430.       break;
  431.   }
  432. }
  433.  
  434. ///////////////////////////////////////////////////////////////////////////////
  435. // Read a BYTE, WORD, or LONG from memory
  436. ///////////////////////////////////////////////////////////////////////////////
  437. int m68000::Peek(unsigned long address, unsigned int& value, int size)
  438. {
  439.   unsigned char c1,c2,c3,c4;
  440.  
  441.   switch (size)
  442.   {
  443.     case BYTE:
  444.       if(address_space->Peek(address,c1))
  445.       {
  446.         value=(unsigned int)c1;
  447.         return(EXECUTE_OK);
  448.       }
  449.       else
  450.       {
  451.         return(EXECUTE_BUS_ERROR);
  452.       }
  453.       break;
  454.  
  455.     case WORD:
  456.       if((address&1)==0)
  457.       { 
  458.         if(address_space->Peek(address,c1) && address_space->Peek(address+1,c2))
  459.         {
  460.           value = (((unsigned int)c1)<<8) | ((unsigned int)c2);
  461.           return(EXECUTE_OK);
  462.         }
  463.         else
  464.         {
  465.           return(EXECUTE_BUS_ERROR);
  466.         }
  467.       }
  468.       else
  469.       {
  470.         return(EXECUTE_ADDRESS_ERROR); 
  471.       }
  472.       break;
  473.  
  474.     default:  // LONG
  475.       if((address&1)==0)
  476.       {
  477.         if(address_space->Peek(address,c1) && address_space->Peek(address+1,c2)
  478.            && address_space->Peek(address+2,c3)
  479.            && address_space->Peek(address+3,c4))
  480.         {
  481.           value = (((unsigned int)c1)<<24) | (((unsigned int)c2)<<16) |
  482.                   (((unsigned int)c3)<<8) | ((unsigned int)c4);
  483.           return(EXECUTE_OK);
  484.         }
  485.         else
  486.         {
  487.           return(EXECUTE_BUS_ERROR);
  488.         }
  489.       }
  490.       else
  491.       {
  492.         return(EXECUTE_ADDRESS_ERROR);
  493.       }
  494.       break;
  495.   }
  496. }
  497.  
  498. ///////////////////////////////////////////////////////////////////////////////
  499. // Write a BYTE, WORD, or LONG to memory
  500. ///////////////////////////////////////////////////////////////////////////////
  501. int m68000::Poke(unsigned long address, unsigned int value, int size)
  502. {
  503.   switch (size)
  504.   {
  505.     case BYTE:
  506.       if(address_space->Poke(address,(unsigned char)value))
  507.       {
  508.         return(EXECUTE_OK);
  509.       }
  510.       else
  511.       {
  512.         return(EXECUTE_BUS_ERROR);
  513.       }
  514.       break;
  515.  
  516.     case WORD:
  517.       if((address&1)==0)
  518.       { 
  519.         if(address_space->Poke(address+1,(unsigned char)value) &&
  520.            address_space->Poke(address,(unsigned char)(value>>8)))
  521.         {
  522.           return(EXECUTE_OK);
  523.         }
  524.         else
  525.         {
  526.           return(EXECUTE_BUS_ERROR);
  527.         }
  528.       }
  529.       else
  530.       {
  531.         return(EXECUTE_ADDRESS_ERROR); 
  532.       }
  533.       break;
  534.  
  535.     default:  // LONG
  536.       if((address&1)==0)
  537.       {
  538.         if(address_space->Poke(address+3,(unsigned char)value) &&
  539.            address_space->Poke(address+2,(unsigned char)(value>>8)) &&
  540.            address_space->Poke(address+1,(unsigned char)(value>>16)) &&
  541.            address_space->Poke(address,(unsigned char)(value>>24)))
  542.         {
  543.           return(EXECUTE_OK);
  544.         }
  545.         else
  546.         {
  547.           return(EXECUTE_BUS_ERROR);
  548.         }
  549.       }
  550.       else
  551.       {
  552.         return(EXECUTE_ADDRESS_ERROR);
  553.       }
  554.       break;
  555.   }
  556. }
  557.  
  558. ///////////////////////////////////////////////////////////////////////////////
  559. // Clear the condition codes in the status register given by the mask
  560. ///////////////////////////////////////////////////////////////////////////////
  561. void m68000::ClearConditionCodes(int mask)
  562. {
  563.   if(mask&C_FLAG)
  564.     register_value[SR_INDEX] &= ~C_FLAG;
  565.   else if(mask&V_FLAG)
  566.     register_value[SR_INDEX] &= ~V_FLAG;
  567.   else if(mask&Z_FLAG)
  568.     register_value[SR_INDEX] &= ~Z_FLAG;
  569.   else if(mask&N_FLAG)
  570.     register_value[SR_INDEX] &= ~N_FLAG;
  571.   else if(mask&X_FLAG)
  572.     register_value[SR_INDEX] &= ~X_FLAG;
  573.   else if(mask&T_FLAG)
  574.     register_value[SR_INDEX] &= ~T_FLAG;
  575.   else if(mask&S_FLAG)
  576.     register_value[SR_INDEX] &= ~S_FLAG;
  577. }
  578.  
  579. ///////////////////////////////////////////////////////////////////////////////
  580. // Set the condition codes in the status register
  581. ///////////////////////////////////////////////////////////////////////////////
  582. void m68000::SetConditionCodes(unsigned int src, unsigned int dest,
  583.                                unsigned int result, int size,
  584.                                int operation, int mask)
  585. {
  586.   int S,D,R;
  587.  
  588.   switch (size) {
  589.     case BYTE: 
  590.       S = (src >> 7) & 1;
  591.       D = (dest >> 7) & 1;
  592.       R = (result >> 7) & 1;
  593.       result = result & 0xff;
  594.       break;
  595.     case WORD: 
  596.       S = (src >> 15) & 1;
  597.       D = (dest >> 15) & 1;
  598.       R = (result >> 15) & 1;
  599.       result = result & 0xffff;
  600.       break;
  601.     case LONG: 
  602.       S = (src >> 31) & 1;
  603.       D = (dest >> 31) & 1;
  604.       R = (result >> 31) & 1;
  605.       result = result & 0xffffffff;
  606.       break;
  607.    }
  608.  
  609.   if(mask&C_FLAG)
  610.   {
  611.     if (operation==ADDITION)
  612.     {
  613.       if((S && D) || (!R && D) || (S && !R))
  614.         register_value[SR_INDEX] |= C_FLAG;
  615.       else
  616.         register_value[SR_INDEX] &= ~C_FLAG;
  617.     }
  618.     else if (operation==SUBTRACTION)
  619.     {
  620.       if((S && !D) || (R && !D) || (S && R))
  621.         register_value[SR_INDEX] |= C_FLAG;
  622.       else
  623.         register_value[SR_INDEX] &= ~C_FLAG;
  624.     }
  625.     else
  626.     {
  627.       register_value[SR_INDEX] &= ~C_FLAG;
  628.     }
  629.   }
  630.  
  631.   if(mask&V_FLAG)
  632.   {
  633.     if (operation==ADDITION)
  634.     {
  635.       if((S && D && !R) || (!S && !D && R))
  636.         register_value[SR_INDEX] |= V_FLAG;
  637.       else
  638.         register_value[SR_INDEX] &= ~V_FLAG;
  639.     }
  640.     else if (operation==SUBTRACTION)
  641.     {
  642.       if((!S && D && !R) || (S && !D && R))
  643.         register_value[SR_INDEX] |= V_FLAG;
  644.       else
  645.         register_value[SR_INDEX] &= ~V_FLAG;
  646.     }
  647.     else
  648.     {
  649.       register_value[SR_INDEX] &= ~V_FLAG;
  650.     }
  651.   }
  652.  
  653.   if(mask&Z_FLAG)
  654.   {
  655.     if(!result)
  656.       register_value[SR_INDEX] |= Z_FLAG;
  657.     else
  658.       register_value[SR_INDEX] &= ~Z_FLAG;
  659.   }
  660.  
  661.   if(mask&N_FLAG)
  662.   {
  663.     if(R)
  664.       register_value[SR_INDEX] |= N_FLAG;
  665.     else
  666.       register_value[SR_INDEX] &= ~N_FLAG;
  667.   }
  668.  
  669.   if(mask&X_FLAG)
  670.   {
  671.     if (operation==ADDITION)
  672.     {
  673.       if((S && D) || (!R && D) || (S && !R))
  674.         register_value[SR_INDEX] |= X_FLAG;
  675.       else
  676.         register_value[SR_INDEX] &= ~X_FLAG;
  677.     }
  678.     else if (operation==SUBTRACTION)
  679.     {
  680.       if((S && !D) || (R && !D) || (S && R))
  681.         register_value[SR_INDEX] |= X_FLAG;
  682.       else
  683.         register_value[SR_INDEX] &= ~X_FLAG;
  684.     }
  685.     else
  686.     {
  687.       register_value[SR_INDEX] &= ~X_FLAG;
  688.     }
  689.   }
  690. }
  691.  
  692. ///////////////////////////////////////////////////////////////////////////////
  693. // Set the regiter to the given value 
  694. ///////////////////////////////////////////////////////////////////////////////
  695. void m68000::SetRegister(int register_number, unsigned int value, int size)
  696. {
  697.   switch (size)
  698.   {
  699.     case BYTE:
  700.       register_value[register_number] &= 0xffffff00;
  701.       register_value[register_number] |= (value&0xff);
  702.       break;
  703.     case WORD:
  704.       register_value[register_number] &= 0xffff0000;
  705.       register_value[register_number] |= (value&0xffff);
  706.       break;
  707.     case LONG:
  708.       register_value[register_number] &= 0x00000000;
  709.       register_value[register_number] |= (value&0xffffffff);
  710.       break;
  711.    } 
  712. }
  713.  
  714. ///////////////////////////////////////////////////////////////////////////////
  715. // Checks the condition codes to see if a branch should occur
  716. ///////////////////////////////////////////////////////////////////////////////
  717. int m68000::CheckConditionCodes(int code, String& mnemonic, int trace)
  718. {
  719.   int branch=0;
  720.   unsigned long sr;
  721.  
  722.   sr=register_value[SR_INDEX];
  723.   switch (code)
  724.   {
  725.     case 4:
  726.       branch=!(sr&C_FLAG); 
  727.       if(trace) mnemonic+="CC";
  728.       break; 
  729.     case 5: 
  730.       branch=(sr&C_FLAG); 
  731.       if(trace) mnemonic+="CS";
  732.       break; 
  733.     case 7:
  734.       branch=(sr&Z_FLAG); 
  735.       if(trace) mnemonic+="EQ";
  736.       break; 
  737.     case 1:
  738.       branch=0;
  739.       if(trace) mnemonic+="F";
  740.       break;
  741.     case 12:
  742.       branch=((sr&N_FLAG) && (sr&V_FLAG)) || (!(sr&N_FLAG) && !(sr&V_FLAG)); 
  743.       if(trace) mnemonic+="GE";
  744.       break; 
  745.     case 14:
  746.       branch=((sr&N_FLAG) && (sr&V_FLAG) && !(sr&Z_FLAG)) ||
  747.              (!(sr&N_FLAG) && !(sr&V_FLAG) && !(sr&Z_FLAG)); 
  748.       if(trace) mnemonic+="GT";
  749.       break; 
  750.     case 2:
  751.       branch=(!(sr&C_FLAG) && !(sr&Z_FLAG)); 
  752.       if(trace) mnemonic+="HI";
  753.       break; 
  754.     case 15:
  755.       branch=(sr&Z_FLAG) || ((sr&N_FLAG) && !(sr&V_FLAG)) ||
  756.              (!(sr&N_FLAG) && (sr&V_FLAG)); 
  757.       if(trace) mnemonic+="LE";
  758.       break; 
  759.     case 3:
  760.       branch=(sr&C_FLAG) || (sr&Z_FLAG);
  761.       if(trace) mnemonic+="LS";
  762.       break; 
  763.     case 13:
  764.       branch=((sr&N_FLAG) && !(sr&V_FLAG)) || (!(sr&N_FLAG) && (sr&V_FLAG)); 
  765.       if(trace) mnemonic+="LT";
  766.       break; 
  767.     case 11:
  768.       branch=(sr&N_FLAG);
  769.       if(trace) mnemonic+="MI";
  770.       break; 
  771.     case 6:
  772.       branch=!(sr&Z_FLAG);
  773.       if(trace) mnemonic+="NE";
  774.       break; 
  775.     case 10:
  776.       branch=!(sr&N_FLAG);
  777.       if(trace) mnemonic+="PL";
  778.       break; 
  779.     case 0:
  780.       branch=1;
  781.       if(trace) mnemonic+="T";
  782.       break;
  783.     case 8:
  784.       branch=!(sr&V_FLAG);
  785.       if(trace) mnemonic+="VC";
  786.       break; 
  787.     case 9:
  788.       branch=(sr&V_FLAG);
  789.       if(trace) mnemonic+="VS";
  790.       break; 
  791.   } 
  792.   return(branch);
  793. }
  794.  
  795.  
  796. ///////////////////////////////////////////////////////////////////////////////
  797. // Execute the '' instruction 
  798. ///////////////////////////////////////////////////////////////////////////////
  799. int m68000::ExecuteABCD(int opcode, String& trace_record, int trace)
  800. {
  801.   return(ExecuteInvalid(opcode, trace_record, trace));
  802. }
  803.  
  804. ///////////////////////////////////////////////////////////////////////////////
  805. // Execute the 'ADD' instruction 
  806. ///////////////////////////////////////////////////////////////////////////////
  807. int m68000::ExecuteADD(int opcode, String& trace_record, int trace)
  808. {
  809.   int status, size, in_register_flag;
  810.   unsigned long ea_address, register_number;
  811.   unsigned int result, ea_data;
  812.   String mnemonic, ea_description;
  813.  
  814.   size=(opcode&0x00c0) >> 6;
  815.  
  816.   // Get the <ea> data address
  817.   if((status=ComputeEffectiveAddress(ea_address, in_register_flag,
  818.                   ea_description, opcode & 0x3f, size, trace)) != EXECUTE_OK)
  819.   { return(status); }
  820.  
  821.   // Fetch the <ea> data 
  822.   if (in_register_flag)
  823.     ea_data=register_value[ea_address];
  824.   else
  825.     if ((status=Peek(ea_address, ea_data, size)) != EXECUTE_OK)
  826.       return(status);
  827.  
  828.   // Get the register number
  829.   register_number=D0_INDEX+((opcode&0x0e00) >> 9);
  830.  
  831.   if(trace)
  832.   {
  833.     mnemonic+="{Mnemonic {ADD";
  834.     if (size==BYTE)
  835.       mnemonic+=".B ";
  836.     else if (size==WORD)
  837.       mnemonic+=".W ";
  838.     else if (size==LONG)
  839.       mnemonic+=".L ";
  840.   }
  841.  
  842.   if(opcode & 0x0100)    // <Dn> + <ea> -> <ea>
  843.   {
  844.     if(trace)
  845.     {
  846.       mnemonic+=register_data[register_number].name;
  847.       mnemonic+=",";
  848.       mnemonic+=ea_description;
  849.     }
  850.     result=register_value[register_number]+ea_data;
  851.     SetConditionCodes(register_value[register_number], ea_data, result, size,
  852.                       ADDITION, C_FLAG|V_FLAG|Z_FLAG|N_FLAG|X_FLAG);
  853.     if((status=Poke(ea_address, result, size)) != EXECUTE_OK)
  854.       return(status);
  855.   }
  856.   else                   // <ea> + <Dn> -> <Dn>
  857.   {
  858.     if(trace)
  859.     {
  860.       mnemonic+=ea_description;
  861.       mnemonic+=",";
  862.       mnemonic+=register_data[register_number].name;
  863.     }
  864.     result=ea_data+register_value[register_number];
  865.     SetConditionCodes(ea_data, register_value[register_number], result, size,
  866.                       ADDITION, C_FLAG|V_FLAG|Z_FLAG|N_FLAG|X_FLAG);
  867.     SetRegister(register_number, result, size);
  868.   }
  869.  
  870.   if(trace)
  871.   {
  872.     mnemonic+="}} ";
  873.     trace_record+=mnemonic;
  874.   }
  875.   return(EXECUTE_OK);
  876. }
  877.  
  878. ///////////////////////////////////////////////////////////////////////////////
  879. // Execute the 'ADDA' instruction 
  880. ///////////////////////////////////////////////////////////////////////////////
  881. int m68000::ExecuteADDA(int opcode, String& trace_record, int trace)
  882.   int status, size, in_register_flag;
  883.   unsigned long ea_address, register_number;
  884.   unsigned int result, ea_data;
  885.   String mnemonic, ea_description;
  886.  
  887.   if (opcode&0x0100)
  888.     size=LONG;
  889.   else
  890.     size=WORD;
  891.  
  892.   // Get the <ea> data address
  893.   if((status=ComputeEffectiveAddress(ea_address, in_register_flag,
  894.                   ea_description, opcode & 0x3f, size, trace)) != EXECUTE_OK)
  895.   { return(status); }
  896.  
  897.   // Fetch the <ea> data 
  898.   if (in_register_flag)
  899.     ea_data=register_value[ea_address];
  900.   else
  901.     if ((status=Peek(ea_address, ea_data, size)) != EXECUTE_OK)
  902.       return(status);
  903.  
  904.   if(size==WORD)
  905.     ea_data=SignExtend(ea_data,WORD);
  906.  
  907.   // Get the register number
  908.   register_number=A0_INDEX+((opcode&0x0e00) >> 9);
  909.  
  910.   // Adjust register_number if it's A7 and we're in supervisor mode
  911.   if((register_number == USP_INDEX) && (register_value[SR_INDEX] & S_FLAG))
  912.     register_number = SSP_INDEX;
  913.  
  914.   result=ea_data+register_value[register_number];
  915.   SetRegister(register_number, result, LONG);
  916.  
  917.   if(trace)
  918.   {
  919.     mnemonic+="{Mnemonic {ADDA";
  920.     if (size==WORD)
  921.       mnemonic+=".W ";
  922.     else if (size==LONG)
  923.       mnemonic+=".L ";
  924.  
  925.     mnemonic+=ea_description;
  926.     mnemonic+=",";
  927.     mnemonic+=register_data[register_number].name;
  928.     mnemonic+="}} ";
  929.     trace_record+=mnemonic;
  930.   }
  931.   return(EXECUTE_OK);
  932. }
  933.  
  934. ///////////////////////////////////////////////////////////////////////////////
  935. // Execute the 'ADDI' instruction 
  936. ///////////////////////////////////////////////////////////////////////////////
  937. int m68000::ExecuteADDI(int opcode, String& trace_record, int trace)
  938. {
  939.   int status, size, in_register;
  940.   unsigned long dest_addr, src_addr;
  941.   unsigned int result, src, dest;
  942.   String mnemonic;
  943.  
  944.   size=(opcode&0x00c0) >> 6;
  945.  
  946.   if(trace)
  947.   {
  948.     mnemonic+="{Mnemonic {ADDI";
  949.     if (size==BYTE)
  950.       mnemonic+=".B ";
  951.     else if (size==WORD)
  952.       mnemonic+=".W ";
  953.     else if (size==LONG)
  954.       mnemonic+=".L ";
  955.   }
  956.  
  957.   // Get the immediate data pointer
  958.   if((status=ComputeEffectiveAddress(src_addr, in_register, mnemonic,
  959.                     0x3c, size, trace)) != EXECUTE_OK)
  960.   { return(status); }
  961.  
  962.   // Fetch the immediate data
  963.   if((status=Peek(src_addr, src, size)) != EXECUTE_OK)
  964.     return(status);
  965.  
  966.   if(trace)
  967.     mnemonic+=",";
  968.  
  969.   // Get the destination data pointer
  970.   if((status=ComputeEffectiveAddress(dest_addr, in_register, mnemonic,
  971.                     opcode & 0x3f, size, trace)) != EXECUTE_OK)
  972.   {
  973.     return(status);
  974.   }
  975.  
  976.   if(in_register)
  977.   {
  978.     dest=register_value[dest_addr];
  979.     result=dest+src;
  980.     SetConditionCodes(src,dest,result,size,
  981.                       ADDITION, C_FLAG|V_FLAG|Z_FLAG|N_FLAG|X_FLAG);
  982.     SetRegister(dest_addr,result,size);
  983.   } 
  984.   else
  985.   {
  986.     if((status=Peek(dest_addr, dest, size)) != EXECUTE_OK)
  987.       return(status);
  988.     result=dest+src;
  989.     SetConditionCodes(src,dest,result,size,
  990.                       ADDITION, C_FLAG|V_FLAG|Z_FLAG|N_FLAG|X_FLAG);
  991.     if((status=Poke(dest_addr, result, size)) != EXECUTE_OK)
  992.       return(status);
  993.   }
  994.  
  995.   if (trace)
  996.   {
  997.     mnemonic+="}} ";
  998.     trace_record+=mnemonic;
  999.   }
  1000.   return(EXECUTE_OK);
  1001. }
  1002.  
  1003. ///////////////////////////////////////////////////////////////////////////////
  1004. // Execute the 'ADDQ' instruction 
  1005. ///////////////////////////////////////////////////////////////////////////////
  1006. int m68000::ExecuteADDQ(int opcode, String& trace_record, int trace)
  1007. {
  1008.   int status, size, in_register_flag;
  1009.   unsigned long ea_address, immediate_data;
  1010.   unsigned int result, ea_data;
  1011.   String ea_description;
  1012.  
  1013.   size=(opcode&0x00c0) >> 6;
  1014.  
  1015.   // Get the immediate data out of the opcode
  1016.   if((immediate_data=(opcode&0x0e00) >> 9) == 0)
  1017.     immediate_data=8;
  1018.  
  1019.   // Get the <ea> data address
  1020.   if((status=ComputeEffectiveAddress(ea_address, in_register_flag,
  1021.                   ea_description, opcode & 0x3f, size, trace)) != EXECUTE_OK)
  1022.   { return(status); }
  1023.  
  1024.   // Fetch the <ea> data 
  1025.   if(in_register_flag)
  1026.     ea_data=register_value[ea_address];
  1027.   else
  1028.     if((status=Peek(ea_address, ea_data, size)) != EXECUTE_OK)
  1029.       return(status);
  1030.  
  1031.   if(in_register_flag)
  1032.   {
  1033.     result=immediate_data+ea_data;
  1034.     if((ea_address>=A0_INDEX) && (ea_address<=SSP_INDEX))
  1035.     {
  1036.       SetRegister(ea_address, result, LONG);
  1037.     }
  1038.     else
  1039.     {
  1040.       SetConditionCodes(immediate_data, ea_data, result, size,
  1041.                         ADDITION, C_FLAG|V_FLAG|Z_FLAG|N_FLAG|X_FLAG);
  1042.       SetRegister(ea_address, result, size);
  1043.     }
  1044.   }
  1045.   else
  1046.   {
  1047.     result=immediate_data+ea_data;
  1048.     SetConditionCodes(immediate_data, ea_data, result, size,
  1049.                       ADDITION, C_FLAG|V_FLAG|Z_FLAG|N_FLAG|X_FLAG);
  1050.     if((status=Poke(ea_address, result, size)) != EXECUTE_OK)
  1051.       return(status);
  1052.   }
  1053.  
  1054.   if(trace)
  1055.   {
  1056.     trace_record+="{Mnemonic {ADDQ";
  1057.     if (size==BYTE)
  1058.       trace_record+=".B ";
  1059.     else if (size==WORD)
  1060.       trace_record+=".W ";
  1061.     else if (size==LONG)
  1062.       trace_record+=".L ";
  1063.     trace_record+="#$";
  1064.     trace_record+=IntToString(immediate_data,1);
  1065.     trace_record+=",";
  1066.     trace_record+=ea_description;
  1067.     trace_record+="}} ";
  1068.   }
  1069.   return(EXECUTE_OK);
  1070. }
  1071.  
  1072. ///////////////////////////////////////////////////////////////////////////////
  1073. // Execute the 'ADDX' instruction 
  1074. ///////////////////////////////////////////////////////////////////////////////
  1075. int m68000::ExecuteADDX(int opcode, String& trace_record, int trace)
  1076. {
  1077.   int status, size, in_register_flag;
  1078.   unsigned long src_address, dest_address;
  1079.   unsigned int result, src, dest;
  1080.   String mnemonic;
  1081.  
  1082.   size = (opcode & 0x00c0) >> 6;
  1083.  
  1084.   if(trace)
  1085.   {
  1086.     mnemonic += "{Mnemonic {ADDX";
  1087.     if (size == BYTE)
  1088.       mnemonic += ".B ";
  1089.     else if (size == WORD)
  1090.       mnemonic += ".W ";
  1091.     else if (size == LONG)
  1092.       mnemonic += ".L ";
  1093.   }
  1094.  
  1095.   // Get the addresses
  1096.   if(opcode & 8)
  1097.   {
  1098.     if((status = ComputeEffectiveAddress(src_address, in_register_flag,
  1099.             mnemonic, 0x20 | (opcode & 7) , size, trace)) != EXECUTE_OK)
  1100.     { return(status); }
  1101.  
  1102.     if(trace)
  1103.       mnemonic += ",";
  1104.  
  1105.     if((status = ComputeEffectiveAddress(dest_address, in_register_flag,
  1106.             mnemonic, 0x20 | ((opcode & 0x0e00) >> 9), size, trace)) != EXECUTE_OK)
  1107.     { return(status); }
  1108.  
  1109.     if((status = Peek(src_address, src, size)) != EXECUTE_OK)
  1110.       return(status);
  1111.     if((status = Peek(dest_address, dest, size)) != EXECUTE_OK)
  1112.       return(status);
  1113.   }
  1114.   else
  1115.   {
  1116.     src_address = D0_INDEX + (opcode & 0x0007);
  1117.     src = register_value[src_address];
  1118.     dest_address = D0_INDEX + ((opcode & 0x0e00) >> 9);
  1119.     dest = register_value[dest_address];
  1120.     if(trace)
  1121.     {
  1122.       mnemonic += register_data[src_address].name;
  1123.       mnemonic += ",";
  1124.       mnemonic += register_data[dest_address].name;
  1125.     }
  1126.   }
  1127.  
  1128.   if(register_value[SR_INDEX] & X_FLAG)
  1129.     result = src + dest + 1;
  1130.   else
  1131.     result = src + dest;
  1132.  
  1133.   if(size == BYTE)
  1134.     result = result&0xff;
  1135.   else if (size == WORD)
  1136.     result = result & 0xffff;
  1137.   else if (size == LONG)
  1138.     result = result & 0xffffffff;
  1139.  
  1140.   SetConditionCodes(src, dest, result, size,
  1141.                     ADDITION, C_FLAG|V_FLAG|N_FLAG|X_FLAG);
  1142.   if(result)
  1143.     register_value[SR_INDEX] &= ~Z_FLAG;
  1144.  
  1145.   if(opcode & 8)
  1146.   {
  1147.     if((status = Poke(dest_address, result, size)) != EXECUTE_OK)
  1148.       return(status);
  1149.   }
  1150.   else
  1151.   {
  1152.     SetRegister(dest_address, result, size);
  1153.   }
  1154.  
  1155.   if(trace)
  1156.   {
  1157.     mnemonic+="}} ";
  1158.     trace_record += mnemonic;
  1159.   }
  1160.   return(EXECUTE_OK);
  1161. }
  1162.  
  1163. ///////////////////////////////////////////////////////////////////////////////
  1164. // Execute the 'AND' instruction 
  1165. ///////////////////////////////////////////////////////////////////////////////
  1166. int m68000::ExecuteAND(int opcode, String& trace_record, int trace)
  1167. {
  1168.   int status, size, in_register_flag;
  1169.   unsigned long ea_address, register_number;
  1170.   unsigned int result, ea_data;
  1171.   String mnemonic, ea_description;
  1172.  
  1173.   size=(opcode&0x00c0) >> 6;
  1174.  
  1175.   // Get the <ea> data address
  1176.   if((status=ComputeEffectiveAddress(ea_address, in_register_flag,
  1177.                   ea_description, opcode & 0x3f, size, trace)) != EXECUTE_OK)
  1178.   { return(status); }
  1179.  
  1180.   // Fetch the <ea> data 
  1181.   if(in_register_flag)
  1182.     ea_data=register_value[ea_address];
  1183.   else
  1184.     if((status=Peek(ea_address, ea_data, size)) != EXECUTE_OK)
  1185.       return(status);
  1186.  
  1187.   // Get the register number
  1188.   register_number=D0_INDEX+((opcode&0x0e00) >> 9);
  1189.  
  1190.   if(trace)
  1191.   {
  1192.     mnemonic+="{Mnemonic {AND";
  1193.     if (size==BYTE)
  1194.       mnemonic+=".B ";
  1195.     else if (size==WORD)
  1196.       mnemonic+=".W ";
  1197.     else if (size==LONG)
  1198.       mnemonic+=".L ";
  1199.   }
  1200.  
  1201.   if(opcode & 0x0100)    // <Dn> & <ea> -> <ea>
  1202.   {
  1203.     if(trace)
  1204.     {
  1205.       mnemonic+=register_data[register_number].name;
  1206.       mnemonic+=",";
  1207.       mnemonic+=ea_description;
  1208.     }
  1209.     result=register_value[register_number]&ea_data;
  1210.     SetConditionCodes(register_value[register_number], ea_data, result, size,
  1211.                       OTHER, V_FLAG|C_FLAG|Z_FLAG|N_FLAG);
  1212.     if((status=Poke(ea_address, result, size)) != EXECUTE_OK)
  1213.       return(status);
  1214.   }
  1215.   else                   // <ea> & <Dn> -> <Dn>
  1216.   {
  1217.     if(trace)
  1218.     {
  1219.       mnemonic+=ea_description;
  1220.       mnemonic+=",";
  1221.       mnemonic+=register_data[register_number].name;
  1222.     }
  1223.     result=ea_data®ister_value[register_number];
  1224.     SetConditionCodes(ea_data, register_value[register_number], result, size,
  1225.                       OTHER, V_FLAG|C_FLAG|Z_FLAG|N_FLAG);
  1226.     SetRegister(register_number, result, size);
  1227.   }
  1228.  
  1229.   if(trace)
  1230.   {
  1231.     mnemonic+="}} ";
  1232.     trace_record+=mnemonic;
  1233.   }
  1234.   return(EXECUTE_OK);
  1235. }
  1236.  
  1237. ///////////////////////////////////////////////////////////////////////////////
  1238. // Execute the 'ANDI' instruction 
  1239. ///////////////////////////////////////////////////////////////////////////////
  1240. int m68000::ExecuteANDI(int opcode, String& trace_record, int trace)
  1241. {
  1242.   int status, size, in_register;
  1243.   unsigned long dest_addr, src_addr;
  1244.   unsigned int result, src, dest;
  1245.   String mnemonic;
  1246.  
  1247.   size=(opcode&0x00c0) >> 6;
  1248.  
  1249.   if(trace)
  1250.   {
  1251.     mnemonic+="{Mnemonic {ANDI";
  1252.     if (size==BYTE)
  1253.       mnemonic+=".B ";
  1254.     else if (size==WORD)
  1255.       mnemonic+=".W ";
  1256.     else if (size==LONG)
  1257.       mnemonic+=".L ";
  1258.   }
  1259.  
  1260.   // Get the immediate data pointer
  1261.   if((status=ComputeEffectiveAddress(src_addr, in_register, mnemonic,
  1262.                     0x3c, size, trace)) != EXECUTE_OK)
  1263.   { return(status); }
  1264.  
  1265.   // Fetch the immediate data
  1266.   if((status=Peek(src_addr, src, size)) != EXECUTE_OK)
  1267.     return(status);
  1268.  
  1269.   if(trace)
  1270.     mnemonic+=",";
  1271.  
  1272.   // Get the destination data pointer
  1273.   if((status=ComputeEffectiveAddress(dest_addr, in_register, mnemonic,
  1274.                     opcode & 0x3f, size, trace)) != EXECUTE_OK)
  1275.   {
  1276.     return(status);
  1277.   }
  1278.  
  1279.   if(in_register)
  1280.   {
  1281.     dest=register_value[dest_addr];
  1282.     result=dest&src;
  1283.     SetConditionCodes(src,dest,result,size,
  1284.                       OTHER, C_FLAG|V_FLAG|Z_FLAG|N_FLAG);
  1285.     SetRegister(dest_addr,result,size);
  1286.   } 
  1287.   else
  1288.   {
  1289.     if((status=Peek(dest_addr, dest, size)) != EXECUTE_OK)
  1290.       return(status);
  1291.     result=dest&src;
  1292.     SetConditionCodes(src,dest,result,size,
  1293.                       OTHER, C_FLAG|V_FLAG|Z_FLAG|N_FLAG);
  1294.     if((status=Poke(dest_addr, result, size)) != EXECUTE_OK)
  1295.       return(status);
  1296.   }
  1297.  
  1298.   if (trace)
  1299.   {
  1300.     mnemonic+="}} ";
  1301.     trace_record+=mnemonic;
  1302.   }
  1303.   return(EXECUTE_OK);
  1304. }
  1305.  
  1306. ///////////////////////////////////////////////////////////////////////////////
  1307. // Execute the 'ANDItoCCR' instruction 
  1308. ///////////////////////////////////////////////////////////////////////////////
  1309. int m68000::ExecuteANDItoCCR(int opcode, String& trace_record, int trace)
  1310. {
  1311.   int status, size, in_register_flag;
  1312.   unsigned long src_addr;
  1313.   unsigned int src;
  1314.   String mnemonic;
  1315.  
  1316.   size=BYTE;
  1317.  
  1318.   if(trace)
  1319.     mnemonic+="{Mnemonic {ANDI.B ";
  1320.  
  1321.   // Get the immediate data pointer
  1322.   if((status=ComputeEffectiveAddress(src_addr, in_register_flag, mnemonic,
  1323.                     0x3c, size, trace)) != EXECUTE_OK)
  1324.   { return(status); }
  1325.  
  1326.   // Fetch the immediate data
  1327.   if((status=Peek(src_addr, src, size)) != EXECUTE_OK)
  1328.     return(status);
  1329.  
  1330.   SetRegister(SR_INDEX, (register_value[SR_INDEX]&src), BYTE);
  1331.   if (trace)
  1332.   {
  1333.     mnemonic+=",CCR}} ";
  1334.     trace_record+=mnemonic;
  1335.   }
  1336.   return(EXECUTE_OK);
  1337. }
  1338.  
  1339. ///////////////////////////////////////////////////////////////////////////////
  1340. // Execute the 'ANDItoSR' instruction 
  1341. ///////////////////////////////////////////////////////////////////////////////
  1342. int m68000::ExecuteANDItoSR(int opcode, String& trace_record, int trace)
  1343. {
  1344.   int status, size, in_register_flag;
  1345.   unsigned long src_addr;
  1346.   unsigned int src;
  1347.   String mnemonic;
  1348.  
  1349.   // Make sure we're in supervisor mode or trap
  1350.   if (!(register_value[SR_INDEX] & S_FLAG))
  1351.   {
  1352.     SetRegister(PC_INDEX, register_value[PC_INDEX]-2, LONG);
  1353.     if((status=ProcessException(8)) != EXECUTE_OK)
  1354.       return(status);
  1355.     if(trace);
  1356.       trace_record+="{Mnemonic {Privilege Violation Exception}} ";
  1357.     return(EXECUTE_PRIVILEGED_OK);
  1358.   }
  1359.  
  1360.   size=WORD;
  1361.  
  1362.   if(trace)
  1363.     mnemonic+="{Mnemonic {ANDI.W ";
  1364.  
  1365.   // Get the immediate data pointer
  1366.   if((status=ComputeEffectiveAddress(src_addr, in_register_flag, mnemonic,
  1367.                     0x3c, size, trace)) != EXECUTE_OK)
  1368.   { return(status); }
  1369.  
  1370.   // Fetch the immediate data
  1371.   if((status=Peek(src_addr, src, size)) != EXECUTE_OK)
  1372.     return(status);
  1373.  
  1374.   SetRegister(SR_INDEX, register_value[SR_INDEX]&src, WORD);
  1375.  
  1376.   if (trace)
  1377.   {
  1378.     mnemonic+=",SR}} ";
  1379.     trace_record+=mnemonic;
  1380.   }
  1381.   return(EXECUTE_PRIVILEGED_OK);
  1382. }
  1383.  
  1384. ///////////////////////////////////////////////////////////////////////////////
  1385. // Execute the 'ASL' instruction 
  1386. ///////////////////////////////////////////////////////////////////////////////
  1387. int m68000::ExecuteASL(int opcode, String& trace_record, int trace)
  1388. {
  1389.   int status, size, in_register_flag, shift_count;
  1390.   unsigned long address;
  1391.   unsigned int data;
  1392.   String ea_description;
  1393.  
  1394.   size=(opcode&0x00c0) >> 6;
  1395.  
  1396.   // Check to see if this is a memory or register shift 
  1397.   if(size == 3)
  1398.   {
  1399.     size=WORD;    // Memory always shifts a word
  1400.  
  1401.     // Get the address
  1402.     if((status=ComputeEffectiveAddress(address,in_register_flag,ea_description,
  1403.                  opcode & 0x3f, size, trace)) != EXECUTE_OK)
  1404.     { return(status); }
  1405.  
  1406.     // Fetch the data
  1407.     if((status=Peek(address, data, size)) != EXECUTE_OK)
  1408.       return(status);
  1409.  
  1410.     // Shift the data to the left by one bit.
  1411.     data=data << 1;
  1412.  
  1413.     // Store the shifted data
  1414.     if((status=Poke(address, data, size)) != EXECUTE_OK)
  1415.       return(status);
  1416.  
  1417.     SetConditionCodes(0, 0, data, size,
  1418.         OTHER, N_FLAG|Z_FLAG|X_FLAG|C_FLAG|V_FLAG); 
  1419.     if(data&0x00010000)
  1420.     {
  1421.       register_value[SR_INDEX] |= C_FLAG;
  1422.       register_value[SR_INDEX] |= X_FLAG;
  1423.     }
  1424.     if(!((data&0x000180000)==0x000180000) && !((data&0x000180000)==0x00000000))
  1425.       register_value[SR_INDEX] |= V_FLAG;
  1426.   }
  1427.   else
  1428.   {
  1429.     // Compute the shift count
  1430.     if(opcode&32)
  1431.     {
  1432.       shift_count=register_value[D0_INDEX+((opcode&0x0e00) >> 9)] & 0x3f;
  1433.       if(trace)
  1434.         ea_description=register_data[D0_INDEX+((opcode&0x0e00) >> 9)].name;
  1435.     }
  1436.     else
  1437.     {
  1438.       if((shift_count=(opcode&0x0e00) >> 9) == 0)
  1439.         shift_count=8;
  1440.  
  1441.       if(trace)
  1442.       {
  1443.         ea_description="#$";
  1444.         ea_description+=IntToString(shift_count,1);
  1445.       }
  1446.     }
  1447.  
  1448.     if(trace)
  1449.     {
  1450.       ea_description+=",";
  1451.       ea_description+=register_data[D0_INDEX+(opcode&7)].name;
  1452.     }
  1453.  
  1454.     unsigned int carry, overflow=0;
  1455.     unsigned int carry_mask, overflow_mask;
  1456.  
  1457.     // Setup masks
  1458.     if(size==BYTE)
  1459.     {
  1460.       carry_mask=0x80;
  1461.       overflow_mask=0xc0;
  1462.     }
  1463.     else if(size==WORD)
  1464.     {
  1465.       carry_mask=0x8000;
  1466.       overflow_mask=0xc000;
  1467.     }
  1468.     else
  1469.     {
  1470.       carry_mask=0x80000000;
  1471.       overflow_mask=0xc0000000;
  1472.     }
  1473.  
  1474.     // Perform the shift on the data
  1475.     data=register_value[D0_INDEX+(opcode&7)];
  1476.     for(int t=0;t<shift_count;++t)
  1477.     {
  1478.       carry=data & carry_mask;
  1479.       if(!((data&overflow_mask)==overflow_mask) && !((data&overflow_mask)==0))
  1480.         overflow |= 1;
  1481.  
  1482.       data=data << 1;
  1483.     }
  1484.  
  1485.     SetRegister(D0_INDEX+(opcode&7), data, size);
  1486.  
  1487.     SetConditionCodes(0, 0, data, size,
  1488.         OTHER, N_FLAG|Z_FLAG|X_FLAG|C_FLAG|V_FLAG); 
  1489.     if(overflow)
  1490.       register_value[SR_INDEX] |= V_FLAG;
  1491.     if(carry)
  1492.     {
  1493.       register_value[SR_INDEX] |= C_FLAG;
  1494.       register_value[SR_INDEX] |= X_FLAG;
  1495.     }
  1496.   }
  1497.  
  1498.   if (trace)
  1499.   {
  1500.     trace_record+="{Mnemonic {ASL";
  1501.     if(size==BYTE)
  1502.       trace_record+=".B ";
  1503.     else if(size==WORD)
  1504.       trace_record+=".W ";
  1505.     else if(size==LONG)
  1506.       trace_record+=".L ";
  1507.     trace_record+=ea_description;
  1508.     trace_record+="}} ";
  1509.   }
  1510.   return(EXECUTE_OK);
  1511. }
  1512.  
  1513. ///////////////////////////////////////////////////////////////////////////////
  1514. // Execute the 'ASR' instruction 
  1515. ///////////////////////////////////////////////////////////////////////////////
  1516. int m68000::ExecuteASR(int opcode, String& trace_record, int trace)
  1517. {
  1518.   int status, size, in_register_flag, shift_count;
  1519.   unsigned long address;
  1520.   unsigned int data;
  1521.   String ea_description;
  1522.  
  1523.   size=(opcode&0x00c0) >> 6;
  1524.  
  1525.   // Check to see if this is a memory or register shift 
  1526.   if(size == 3)
  1527.   {
  1528.     size=WORD;    // Memory always shifts a word
  1529.  
  1530.     // Get the address
  1531.     if((status=ComputeEffectiveAddress(address,in_register_flag,ea_description,
  1532.                  opcode & 0x3f, size, trace)) != EXECUTE_OK)
  1533.     { return(status); }
  1534.  
  1535.     // Fetch the data
  1536.     if((status=Peek(address, data, size)) != EXECUTE_OK)
  1537.       return(status);
  1538.  
  1539.     // Set the condition codes
  1540.     SetConditionCodes(0, 0, data >> 1, size,
  1541.         OTHER, N_FLAG|Z_FLAG|X_FLAG|C_FLAG|V_FLAG); 
  1542.     if(data&0x0001)
  1543.     {
  1544.       register_value[SR_INDEX] |= C_FLAG;
  1545.       register_value[SR_INDEX] |= X_FLAG;
  1546.     }
  1547.  
  1548.     // Shift the data to the right by one bit.
  1549.     data=data >> 1;
  1550.  
  1551.     // Replicate the old high order bit
  1552.     if(data & 0x4000)
  1553.       data |= 0x8000;
  1554.     else
  1555.       data &= ~0x8000;
  1556.  
  1557.     // Store the shifted data
  1558.     if((status=Poke(address, data, size)) != EXECUTE_OK)
  1559.       return(status);
  1560.   }
  1561.   else
  1562.   {
  1563.     // Compute the shift count
  1564.     if(opcode&32)
  1565.     {
  1566.       shift_count=register_value[D0_INDEX+((opcode&0x0e00) >> 9)] & 0x3f;
  1567.       if(trace)
  1568.         ea_description=register_data[D0_INDEX+((opcode&0x0e00) >> 9)].name;
  1569.     }
  1570.     else
  1571.     {
  1572.       if((shift_count=(opcode&0x0e00) >> 9) == 0)
  1573.         shift_count=8;
  1574.  
  1575.       if(trace)
  1576.       {
  1577.         ea_description="#$";
  1578.         ea_description+=IntToString(shift_count,1);
  1579.       }
  1580.     }
  1581.  
  1582.     if(trace)
  1583.     {
  1584.       ea_description+=",";
  1585.       ea_description+=register_data[D0_INDEX+(opcode&7)].name;
  1586.     }
  1587.  
  1588.     unsigned int carry, replicate_mask, msb;
  1589.  
  1590.     // Setup masks
  1591.     if(size==BYTE)
  1592.     {
  1593.       replicate_mask=0x40;
  1594.       msb=0x80;
  1595.     }
  1596.     else if(size==WORD)
  1597.     {
  1598.       replicate_mask=0x4000;
  1599.       msb=0x8000;
  1600.     }
  1601.     else
  1602.     {
  1603.       replicate_mask=0x40000000;
  1604.       msb=0x80000000;
  1605.     }
  1606.  
  1607.     // Perform the shift on the data
  1608.     data=register_value[D0_INDEX+(opcode&7)];
  1609.     for(int t=0;t<shift_count;++t)
  1610.     {
  1611.       carry=data & 0x00000001;
  1612.       data=data >> 1;
  1613.  
  1614.       // Replicate the old high order bit
  1615.       if(data & replicate_mask)
  1616.         data |= msb;
  1617.       else
  1618.         data &= ~msb;
  1619.     }
  1620.  
  1621.     SetRegister(D0_INDEX+(opcode&7), data, size);
  1622.  
  1623.     SetConditionCodes(0, 0, data, size,
  1624.         OTHER, N_FLAG|Z_FLAG|X_FLAG|C_FLAG|V_FLAG); 
  1625.     if(carry)
  1626.     {
  1627.       register_value[SR_INDEX] |= C_FLAG;
  1628.       register_value[SR_INDEX] |= X_FLAG;
  1629.     }
  1630.   }
  1631.  
  1632.   if (trace)
  1633.   {
  1634.     trace_record+="{Mnemonic {ASR";
  1635.     if(size==BYTE)
  1636.       trace_record+=".B ";
  1637.     else if(size==WORD)
  1638.       trace_record+=".W ";
  1639.     else if(size==LONG)
  1640.       trace_record+=".L ";
  1641.     trace_record+=ea_description;
  1642.     trace_record+="}} ";
  1643.   }
  1644.   return(EXECUTE_OK);
  1645. }
  1646.  
  1647. ///////////////////////////////////////////////////////////////////////////////
  1648. // Execute the 'Bit' instructions (BCHG, BCLR, BSET, & BTST)
  1649. ///////////////////////////////////////////////////////////////////////////////
  1650. int m68000::ExecuteBit(int opcode, String& trace_record, int trace)
  1651. {
  1652.   int status, size, in_register_flag;
  1653.   unsigned long ea_address, register_number;
  1654.   unsigned int ea_data, bit_number;
  1655.   String mnemonic, ea_description;
  1656.  
  1657.   // Get the bit number we're supposed to be checking
  1658.   if(opcode & 256)
  1659.   { 
  1660.     register_number=D0_INDEX+((opcode&0x0e00) >> 9);
  1661.     bit_number=register_value[register_number];
  1662.     if(trace)
  1663.       ea_description=register_data[register_number].name;
  1664.   }
  1665.   else
  1666.   {
  1667.     unsigned long address;
  1668.  
  1669.     // Get the immediate data pointer
  1670.     if((status=ComputeEffectiveAddress(address, in_register_flag,
  1671.                    ea_description, 0x3c, WORD, trace)) != EXECUTE_OK)
  1672.     { return(status); }
  1673.  
  1674.     // Fetch the immediate data
  1675.     if((status=Peek(address, bit_number, WORD)) != EXECUTE_OK)
  1676.       return(status);
  1677.   }
  1678.  
  1679.   if(trace) ea_description+=",";
  1680.  
  1681.   // Determine the size of the operation (BYTE or LONG)
  1682.   if((opcode & 0x38) == 0)
  1683.     size = LONG;
  1684.   else
  1685.     size = BYTE;
  1686.  
  1687.   // Get the <ea> data address
  1688.   if((status=ComputeEffectiveAddress(ea_address, in_register_flag,
  1689.                   ea_description, opcode & 0x3f, size, trace)) != EXECUTE_OK)
  1690.   { return(status); }
  1691.  
  1692.   // Fetch the <ea> data 
  1693.   if(in_register_flag)
  1694.   {
  1695.     ea_data=register_value[ea_address];
  1696.     bit_number = (1 << (bit_number & 0x1F));
  1697.   }
  1698.   else
  1699.   {
  1700.     if((status=Peek(ea_address, ea_data, BYTE)) != EXECUTE_OK)
  1701.       return(status);
  1702.     bit_number = (1 << (bit_number & 0x07));
  1703.   }
  1704.  
  1705.   // Set the Zero Flag
  1706.   if(ea_data & bit_number)
  1707.     register_value[SR_INDEX] &= ~Z_FLAG;
  1708.   else
  1709.     register_value[SR_INDEX] |= Z_FLAG;
  1710.  
  1711.   switch ((opcode & 0x00c0) >> 6)
  1712.   {
  1713.     case 0:    // BTST
  1714.       if(trace)
  1715.         mnemonic+="{Mnemonic {BTST";
  1716.       break;
  1717.  
  1718.     case 1:    // BCHG
  1719.       if(trace)
  1720.         mnemonic+="{Mnemonic {BCHG";
  1721.       if(ea_data & bit_number)
  1722.         ea_data &= ~bit_number;
  1723.       else
  1724.         ea_data |= bit_number;
  1725.       break;
  1726.  
  1727.     case 2:    // BCLR
  1728.       if(trace)
  1729.         mnemonic+="{Mnemonic {BCLR";
  1730.       ea_data &= ~bit_number;
  1731.       break;
  1732.  
  1733.     case 3:    // BSET
  1734.       if(trace)
  1735.         mnemonic+="{Mnemonic {BSET";
  1736.       ea_data |= bit_number;
  1737.       break;
  1738.   }
  1739.  
  1740.   // If it's not BTST then write the result back
  1741.   if(((opcode & 0x00c0) >> 6)!=0)
  1742.   {
  1743.     if(in_register_flag)
  1744.       SetRegister(ea_address, ea_data, LONG);
  1745.     else
  1746.       if((status=Poke(ea_address, ea_data, BYTE)) != EXECUTE_OK)
  1747.         return(status);
  1748.   }
  1749.  
  1750.   if(trace)
  1751.   {
  1752.     if(size==BYTE)
  1753.       mnemonic+=".B ";
  1754.     else
  1755.       mnemonic+=".L ";
  1756.     trace_record+=mnemonic;
  1757.     trace_record+=ea_description;
  1758.     trace_record+="}} ";
  1759.   }
  1760.   return(EXECUTE_OK);
  1761. }
  1762.  
  1763. ///////////////////////////////////////////////////////////////////////////////
  1764. // Execute the 'BRA' instruction 
  1765. ///////////////////////////////////////////////////////////////////////////////
  1766. int m68000::ExecuteBRA(int opcode, String& trace_record, int trace)
  1767. {
  1768.   unsigned int displacement, status;
  1769.   String mnemonic;
  1770.  
  1771.   if(trace) mnemonic="{Mnemonic {BRA";
  1772.  
  1773.   // Compute the displacement
  1774.   if((displacement=opcode&0xff)==0)
  1775.   {
  1776.     // Fetch the 16-bit displacement data
  1777.     status=Peek(register_value[PC_INDEX],displacement,WORD);
  1778.     if (status!=EXECUTE_OK)
  1779.       return(status);
  1780.  
  1781.     displacement=SignExtend(displacement,WORD);
  1782.     if (trace)
  1783.     {
  1784.       mnemonic+=".W $";
  1785.       mnemonic+=IntToString(displacement,4);
  1786.       mnemonic+="}} ";
  1787.       trace_record+=mnemonic;
  1788.     } 
  1789.   }
  1790.   else
  1791.   {
  1792.     displacement=SignExtend(displacement,BYTE);
  1793.     if (trace)
  1794.     {
  1795.       mnemonic+=".B $";
  1796.       mnemonic+=IntToString(displacement,2);
  1797.       mnemonic+="}} ";
  1798.       trace_record+=mnemonic;
  1799.     } 
  1800.   }
  1801.  
  1802.   SetRegister(PC_INDEX, register_value[PC_INDEX]+displacement, LONG);
  1803.   return(EXECUTE_OK);
  1804. }
  1805.  
  1806. ///////////////////////////////////////////////////////////////////////////////
  1807. // Execute the 'BSR' instruction 
  1808. ///////////////////////////////////////////////////////////////////////////////
  1809. int m68000::ExecuteBSR(int opcode, String& trace_record, int trace)
  1810. {
  1811.   unsigned int displacement, status;
  1812.   unsigned long addr;
  1813.   String mnemonic;
  1814.  
  1815.   if(trace) mnemonic="{Mnemonic {BSR";
  1816.  
  1817.   // Compute the displacement
  1818.   if((displacement=opcode&0xff)==0)
  1819.   {
  1820.     // Fetch the 16-bit displacement data
  1821.     status=Peek(register_value[PC_INDEX],displacement,WORD);
  1822.     if (status!=EXECUTE_OK)
  1823.       return(status);
  1824.  
  1825.     displacement=SignExtend(displacement,WORD);
  1826.     if(trace)
  1827.     {
  1828.       mnemonic+=".W $";
  1829.       mnemonic+=IntToString(displacement,4);
  1830.       mnemonic+="}} ";
  1831.     } 
  1832.   }
  1833.   else
  1834.   {
  1835.     displacement=SignExtend(displacement,BYTE);
  1836.     if(trace)
  1837.     {
  1838.       mnemonic+=".B $";
  1839.       mnemonic+=IntToString(displacement,2);
  1840.       mnemonic+="}}  ";
  1841.     } 
  1842.   }
  1843.  
  1844.   // Push the PC onto the stack
  1845.   if(register_value[SR_INDEX] & S_FLAG)
  1846.   {
  1847.     SetRegister(SSP_INDEX, register_value[SSP_INDEX]-4, LONG);
  1848.     addr=register_value[SSP_INDEX];
  1849.   }
  1850.   else
  1851.   {
  1852.     SetRegister(USP_INDEX, register_value[USP_INDEX]-4, LONG);
  1853.     addr=register_value[USP_INDEX];
  1854.   }
  1855.  
  1856.   if((opcode&0xff)==0)
  1857.   {
  1858.     if((status=Poke(addr, register_value[PC_INDEX]+2, LONG)) != EXECUTE_OK)
  1859.       return(status);
  1860.   }
  1861.   else
  1862.   {
  1863.     if((status=Poke(addr, register_value[PC_INDEX], LONG)) != EXECUTE_OK)
  1864.       return(status);
  1865.   }
  1866.  
  1867.   SetRegister(PC_INDEX, register_value[PC_INDEX]+displacement, LONG);
  1868.  
  1869.   if(trace)
  1870.     trace_record+=mnemonic;
  1871.  
  1872.   return(EXECUTE_OK);
  1873. }
  1874.  
  1875. ///////////////////////////////////////////////////////////////////////////////
  1876. // Execute the 'Bcc' instructions 
  1877. ///////////////////////////////////////////////////////////////////////////////
  1878. int m68000::ExecuteBcc(int opcode, String& trace_record, int trace)
  1879. {
  1880.   unsigned int displacement, branch, status;
  1881.   String mnemonic;
  1882.  
  1883.   // Compute the displacement
  1884.   if((displacement=opcode&0xff)==0)
  1885.   {
  1886.     // Fetch the 16-bit displacement data
  1887.     status=Peek(register_value[PC_INDEX],displacement,WORD);
  1888.     if (status!=EXECUTE_OK)
  1889.       return(status);
  1890.   }
  1891.  
  1892.   if(trace) mnemonic="{Mnemonic {B";
  1893.  
  1894.   // See if the branch should occur
  1895.   branch=CheckConditionCodes((opcode & 0x0f00) >> 8, mnemonic, trace);
  1896.  
  1897.   if((opcode&0xff)==0) 
  1898.   {
  1899.     if(trace)
  1900.     {
  1901.       mnemonic+=".W $";
  1902.       mnemonic+=IntToString(displacement,4);
  1903.     }
  1904.     displacement=SignExtend(displacement,WORD);
  1905.   }
  1906.   else
  1907.   {
  1908.     if(trace)
  1909.     {
  1910.       mnemonic+=".B $";
  1911.       mnemonic+=IntToString(displacement,2);
  1912.     }
  1913.     displacement=SignExtend(displacement,BYTE);
  1914.   }
  1915.  
  1916.   if(branch)
  1917.     SetRegister(PC_INDEX, register_value[PC_INDEX]+displacement, LONG);
  1918.   else if ((opcode&0xff)==0)
  1919.     SetRegister(PC_INDEX, register_value[PC_INDEX]+2, LONG);
  1920.  
  1921.   if(trace)
  1922.   {
  1923.     mnemonic+="}} ";
  1924.     trace_record+=mnemonic;
  1925.   }
  1926.   return(EXECUTE_OK);
  1927. }
  1928.  
  1929. ///////////////////////////////////////////////////////////////////////////////
  1930. // Execute the '' instruction 
  1931. ///////////////////////////////////////////////////////////////////////////////
  1932. int m68000::ExecuteCHK(int opcode, String& trace_record, int trace)
  1933.   return(ExecuteInvalid(opcode, trace_record, trace));
  1934. }
  1935.  
  1936. ///////////////////////////////////////////////////////////////////////////////
  1937. // Execute the 'CLR' instruction
  1938. ///////////////////////////////////////////////////////////////////////////////
  1939. int m68000::ExecuteCLR(int opcode, String& trace_record, int trace)
  1940. {
  1941.   int status, size, in_register;
  1942.   unsigned long address;
  1943.   String mnemonic;
  1944.  
  1945.   size=(opcode&0x00c0) >> 6;
  1946.  
  1947.   if(trace)
  1948.   {
  1949.     mnemonic+="{Mnemonic {CLR";
  1950.     if (size==BYTE)
  1951.       mnemonic+=".B ";
  1952.     else if (size==WORD)
  1953.       mnemonic+=".W ";
  1954.     else if (size==LONG)
  1955.       mnemonic+=".L ";
  1956.   }
  1957.  
  1958.   // Get the destination data pointer
  1959.   if((status=ComputeEffectiveAddress(address, in_register, mnemonic,
  1960.                     opcode & 0x3f, size, trace)) != EXECUTE_OK)
  1961.   { return(status); }
  1962.  
  1963.   if(in_register)
  1964.   {
  1965.     SetConditionCodes(0, 0, 0, size, OTHER, C_FLAG|V_FLAG|Z_FLAG|N_FLAG);
  1966.     SetRegister(address, 0, size);
  1967.   }
  1968.   else
  1969.   {
  1970.     SetConditionCodes(0, 0, 0, size, OTHER, C_FLAG|V_FLAG|Z_FLAG|N_FLAG);
  1971.     if((status=Poke(address, 0, size)) != EXECUTE_OK)
  1972.       return(status);
  1973.   }
  1974.  
  1975.   if (trace)
  1976.   {
  1977.     mnemonic+="}} ";
  1978.     trace_record+=mnemonic;
  1979.   }
  1980.   return(EXECUTE_OK);
  1981. }
  1982.  
  1983. ///////////////////////////////////////////////////////////////////////////////
  1984. // Execute the 'CMP' instruction
  1985. ///////////////////////////////////////////////////////////////////////////////
  1986. int m68000::ExecuteCMP(int opcode, String& trace_record, int trace)
  1987. {
  1988.   int status, size, in_register_flag;
  1989.   unsigned long ea_address, register_number;
  1990.   unsigned int result, ea_data;
  1991.   String mnemonic, ea_description;
  1992.  
  1993.   size=(opcode&0x00c0) >> 6;
  1994.  
  1995.   // Get the <ea> data address
  1996.   if((status=ComputeEffectiveAddress(ea_address, in_register_flag,
  1997.                   ea_description, opcode & 0x3f, size, trace)) != EXECUTE_OK)
  1998.   { return(status); }
  1999.  
  2000.   // Fetch the <ea> data
  2001.   if(in_register_flag)
  2002.     ea_data=register_value[ea_address];
  2003.   else
  2004.     if((status=Peek(ea_address, ea_data, size)) != EXECUTE_OK)
  2005.       return(status);
  2006.  
  2007.   // Get the register number
  2008.   register_number=D0_INDEX+((opcode&0x0e00) >> 9);
  2009.  
  2010.   result=register_value[register_number]-ea_data;
  2011.   SetConditionCodes(ea_data, register_value[register_number], result, size,
  2012.                     SUBTRACTION, C_FLAG|V_FLAG|Z_FLAG|N_FLAG);
  2013.  
  2014.   if(trace)
  2015.   {
  2016.     mnemonic+="{Mnemonic {CMP";
  2017.     if (size==BYTE)
  2018.       mnemonic+=".B ";
  2019.     else if (size==WORD)
  2020.       mnemonic+=".W ";
  2021.     else if (size==LONG)
  2022.       mnemonic+=".L ";
  2023.     mnemonic+=ea_description;
  2024.     mnemonic+=",";
  2025.     mnemonic+=register_data[register_number].name;
  2026.     mnemonic+="}} ";
  2027.     trace_record+=mnemonic;
  2028.   }
  2029.   return(EXECUTE_OK);
  2030. }
  2031.  
  2032. ///////////////////////////////////////////////////////////////////////////////
  2033. // Execute the 'CMPA' instruction
  2034. ///////////////////////////////////////////////////////////////////////////////
  2035. int m68000::ExecuteCMPA(int opcode, String& trace_record, int trace)
  2036. {
  2037.   int status, size, in_register_flag;
  2038.   unsigned long ea_address, register_number;
  2039.   unsigned int result, ea_data;
  2040.   String mnemonic, ea_description;
  2041.  
  2042.   if(opcode&0x0100)
  2043.     size=LONG;
  2044.   else
  2045.     size=WORD;
  2046.  
  2047.   // Get the <ea> data address
  2048.   if((status=ComputeEffectiveAddress(ea_address, in_register_flag,
  2049.                   ea_description, opcode & 0x3f, size, trace)) != EXECUTE_OK)
  2050.   { return(status); }
  2051.  
  2052.   // Fetch the <ea> data
  2053.   if(in_register_flag)
  2054.     ea_data=register_value[ea_address];
  2055.   else
  2056.     if((status=Peek(ea_address, ea_data, size)) != EXECUTE_OK)
  2057.       return(status);
  2058.  
  2059.   ea_data=SignExtend(ea_data,size);
  2060.    
  2061.   // Get the register number
  2062.   register_number=A0_INDEX+((opcode&0x0e00) >> 9);
  2063.  
  2064.   // Adjust register_number if it's A7 and we're in supervisor mode
  2065.   if((register_number == USP_INDEX) && (register_value[SR_INDEX] & S_FLAG))
  2066.     register_number = SSP_INDEX;
  2067.  
  2068.   result=register_value[register_number]-ea_data;
  2069.   SetConditionCodes(ea_data, register_value[register_number], result, size,
  2070.                     SUBTRACTION, C_FLAG|V_FLAG|Z_FLAG|N_FLAG);
  2071.   if(trace)
  2072.   {
  2073.     mnemonic+="{Mnemonic {CMPA";
  2074.     if (size==WORD)
  2075.       mnemonic+=".W ";
  2076.     else if (size==LONG)
  2077.       mnemonic+=".L ";
  2078.     mnemonic+=ea_description;
  2079.     mnemonic+=",";
  2080.     mnemonic+=register_data[register_number].name;
  2081.     mnemonic+="}} ";
  2082.     trace_record+=mnemonic;
  2083.   }
  2084.   return(EXECUTE_OK);
  2085. }
  2086.  
  2087. ///////////////////////////////////////////////////////////////////////////////
  2088. // Execute the 'CMPI' instruction 
  2089. ///////////////////////////////////////////////////////////////////////////////
  2090. int m68000::ExecuteCMPI(int opcode, String& trace_record, int trace)
  2091. {
  2092.   int status, size, in_register;
  2093.   unsigned long dest_addr, src_addr;
  2094.   unsigned int result, src, dest;
  2095.   String mnemonic;
  2096.  
  2097.   size=(opcode&0x00c0) >> 6;
  2098.  
  2099.   if(trace)
  2100.   {
  2101.     mnemonic+="{Mnemonic {CMPI";
  2102.     if (size==BYTE)
  2103.       mnemonic+=".B ";
  2104.     else if (size==WORD)
  2105.       mnemonic+=".W ";
  2106.     else if (size==LONG)
  2107.       mnemonic+=".L ";
  2108.   }
  2109.  
  2110.   // Get the immediate data pointer
  2111.   if((status=ComputeEffectiveAddress(src_addr, in_register, mnemonic,
  2112.                     0x3c, size, trace)) != EXECUTE_OK)
  2113.   { return(status); }
  2114.  
  2115.   // Fetch the immediate data
  2116.   if((status=Peek(src_addr, src, size)) != EXECUTE_OK)
  2117.     return(status);
  2118.  
  2119.   if(trace)
  2120.     mnemonic+=",";
  2121.  
  2122.   // Get the destination data pointer
  2123.   if((status=ComputeEffectiveAddress(dest_addr, in_register, mnemonic,
  2124.                     opcode & 0x3f, size, trace)) != EXECUTE_OK)
  2125.   {
  2126.     return(status);
  2127.   }
  2128.  
  2129.   if(in_register)
  2130.   {
  2131.     dest=register_value[dest_addr];
  2132.     result=dest-src;
  2133.     SetConditionCodes(src, dest, result, size,
  2134.                       SUBTRACTION, C_FLAG|V_FLAG|Z_FLAG|N_FLAG);
  2135.   } 
  2136.   else
  2137.   {
  2138.     if((status=Peek(dest_addr, dest, size)) != EXECUTE_OK)
  2139.       return(status);
  2140.     result=dest-src;
  2141.     SetConditionCodes(src, dest, result, size,
  2142.                       SUBTRACTION, C_FLAG|V_FLAG|Z_FLAG|N_FLAG);
  2143.   }
  2144.  
  2145.   if (trace)
  2146.   {
  2147.     mnemonic+="}} ";
  2148.     trace_record+=mnemonic;
  2149.   }
  2150.   return(EXECUTE_OK);
  2151. }
  2152.  
  2153. ///////////////////////////////////////////////////////////////////////////////
  2154. // Execute the 'CMPM' instruction
  2155. ///////////////////////////////////////////////////////////////////////////////
  2156. int m68000::ExecuteCMPM(int opcode, String& trace_record, int trace)
  2157. {
  2158.   int status, size, in_register_flag;
  2159.   unsigned long src_address, dest_address;
  2160.   unsigned int result, src, dest;
  2161.   String mnemonic;
  2162.  
  2163.   size = (opcode & 0x00c0) >> 6;
  2164.  
  2165.   if(trace)
  2166.   {
  2167.     mnemonic += "{Mnemonic {CMPM";
  2168.     if(size == BYTE)
  2169.       mnemonic += ".B ";
  2170.     else if(size == WORD)
  2171.       mnemonic += ".W ";
  2172.     else if(size == LONG)
  2173.       mnemonic += ".L ";
  2174.   }
  2175.  
  2176.   // Get the addresses
  2177.   if((status = ComputeEffectiveAddress(src_address, in_register_flag,
  2178.           mnemonic, 0x18 | (opcode&7) , size, trace)) != EXECUTE_OK)
  2179.   { return(status); }
  2180.  
  2181.   if (trace) mnemonic += ",";
  2182.  
  2183.   if((status = ComputeEffectiveAddress(dest_address, in_register_flag,
  2184.           mnemonic, 0x18 | ((opcode&0x0e00)>>9), size, trace)) != EXECUTE_OK)
  2185.   { return(status); }
  2186.  
  2187.   if((status = Peek(src_address, src, size)) != EXECUTE_OK)
  2188.     return(status);
  2189.   if((status = Peek(dest_address, dest, size)) != EXECUTE_OK)
  2190.     return(status);
  2191.  
  2192.   result = dest - src;
  2193.   SetConditionCodes(src, dest, result, size,
  2194.                     SUBTRACTION, C_FLAG|V_FLAG|N_FLAG|Z_FLAG);
  2195.  
  2196.   if(trace)
  2197.   {
  2198.     mnemonic += "}} ";
  2199.     trace_record += mnemonic;
  2200.   }
  2201.   return(EXECUTE_OK);
  2202. }
  2203.  
  2204. ///////////////////////////////////////////////////////////////////////////////
  2205. // Execute the 'DBcc' instruction 
  2206. ///////////////////////////////////////////////////////////////////////////////
  2207. int m68000::ExecuteDBcc(int opcode, String& trace_record, int trace)
  2208. {
  2209.   unsigned int displacement, status, register_number, condition_code;
  2210.   String mnemonic;
  2211.  
  2212.   if(trace) mnemonic="{Mnemonic {DB";
  2213.  
  2214.   // Fetch the 16-bit displacement data
  2215.   if((status=Peek(register_value[PC_INDEX],displacement,WORD)) != EXECUTE_OK)
  2216.     return(status);
  2217.  
  2218.   displacement=SignExtend(displacement,WORD);
  2219.  
  2220.   // Check the condition code
  2221.   condition_code=CheckConditionCodes((opcode & 0x0f00) >> 8, mnemonic, trace);
  2222.  
  2223.   // Get the register number that we are counting with 
  2224.   register_number = D0_INDEX+(opcode&7);
  2225.  
  2226.   if(trace)
  2227.   {
  2228.     mnemonic+=".W ";
  2229.     mnemonic+=register_data[register_number].name;
  2230.     mnemonic+=",$";
  2231.     mnemonic+=IntToString(displacement,4);
  2232.   }
  2233.  
  2234.   // If condition code is not true then preform Decrement and Branch
  2235.   if(!condition_code)
  2236.   {
  2237.     SetRegister(register_number, register_value[register_number]-1, WORD);
  2238.     if((register_value[register_number]&0xffff) == 0xffff)
  2239.       SetRegister(PC_INDEX, register_value[PC_INDEX]+2, LONG);
  2240.     else
  2241.       SetRegister(PC_INDEX, register_value[PC_INDEX]+displacement, LONG);
  2242.   }
  2243.   else
  2244.   {
  2245.     SetRegister(PC_INDEX, register_value[PC_INDEX]+2, LONG);
  2246.   }
  2247.  
  2248.   if(trace)
  2249.   {
  2250.     mnemonic+="}} ";
  2251.     trace_record+=mnemonic;
  2252.   }
  2253.   return(EXECUTE_OK);
  2254. }
  2255.  
  2256. ///////////////////////////////////////////////////////////////////////////////
  2257. // Execute the 'DIVS' instruction 
  2258. ///////////////////////////////////////////////////////////////////////////////
  2259. int m68000::ExecuteDIVS(int opcode, String& trace_record, int trace)
  2260. {
  2261.   int status, in_register_flag, positive_result;
  2262.   unsigned long ea_address, register_number;
  2263.   int ea_data, high_result, low_result, data;
  2264.   String ea_description;
  2265.  
  2266.   // Get the <ea> data address
  2267.   if((status=ComputeEffectiveAddress(ea_address, in_register_flag,
  2268.                   ea_description, opcode & 0x3f, WORD, trace)) != EXECUTE_OK)
  2269.   { return(status); }
  2270.  
  2271.   // Fetch the <ea> data
  2272.   if(in_register_flag)
  2273.     ea_data=register_value[ea_address] & 0xffff;
  2274.   else
  2275.   {
  2276.     unsigned int tmp;
  2277.  
  2278.     if((status=Peek(ea_address, tmp, WORD)) != EXECUTE_OK)
  2279.       return(status);
  2280.  
  2281.     ea_data = (int)tmp;
  2282.   } 
  2283.  
  2284.   // Are they trying to divide by zero?
  2285.   if(ea_data==0)
  2286.   {
  2287.     if((status=ProcessException(5)) != EXECUTE_OK)
  2288.       return(status);
  2289.     if(trace);
  2290.       trace_record+="{Mnemonic {Divide by Zero Exception}} ";
  2291.     return(EXECUTE_OK);
  2292.   }
  2293.  
  2294.   // Get the register number
  2295.   register_number=D0_INDEX+((opcode&0x0e00) >> 9);
  2296.   data=register_value[register_number];
  2297.  
  2298.   // Determine the sign of the result
  2299.   if((!(ea_data&0x8000) && !(data&0x8000000)) ||
  2300.       ((ea_data&0x8000) && (data&0x80000000)))
  2301.     positive_result=1;
  2302.   else
  2303.     positive_result=0;
  2304.  
  2305.   // Sign extend the ea_data and the register data
  2306.   ea_data=SignExtend(ea_data,WORD);
  2307.   data=SignExtend(data,LONG);
  2308.  
  2309.   high_result=data % ea_data;
  2310.   high_result=high_result << 16;
  2311.   low_result=data / ea_data;
  2312.  
  2313.   SetRegister(register_number, high_result|(low_result&0xffff), LONG);
  2314.   SetConditionCodes(0, 0, low_result, WORD, OTHER, C_FLAG|Z_FLAG|N_FLAG);
  2315.  
  2316.   // Set the overflow flag
  2317.   if((positive_result && (low_result & 0xffff8000)) ||
  2318.      (!positive_result && (~low_result & 0xffff8000)))
  2319.     register_value[SR_INDEX] |= V_FLAG;
  2320.   else
  2321.     register_value[SR_INDEX] &= ~V_FLAG;
  2322.  
  2323.   if(trace)
  2324.   {
  2325.     trace_record+="{Mnemonic {DIVS.W ";
  2326.     trace_record+=ea_description;
  2327.     trace_record+=",";
  2328.     trace_record+=register_data[register_number].name;
  2329.     trace_record+="}} ";
  2330.   }
  2331.   return(EXECUTE_OK);
  2332. }
  2333.  
  2334. ///////////////////////////////////////////////////////////////////////////////
  2335. // Execute the 'DIVU' instruction 
  2336. ///////////////////////////////////////////////////////////////////////////////
  2337. int m68000::ExecuteDIVU(int opcode, String& trace_record, int trace)
  2338. {
  2339.   int status, in_register_flag;
  2340.   unsigned long ea_address, register_number;
  2341.   unsigned int high_result, low_result, ea_data;
  2342.   String ea_description;
  2343.  
  2344.   // Get the <ea> data address
  2345.   if((status=ComputeEffectiveAddress(ea_address, in_register_flag,
  2346.                   ea_description, opcode & 0x3f, WORD, trace)) != EXECUTE_OK)
  2347.   { return(status); }
  2348.  
  2349.   // Fetch the <ea> data
  2350.   if(in_register_flag)
  2351.     ea_data=register_value[ea_address] & 0xffff;
  2352.   else
  2353.     if((status=Peek(ea_address, ea_data, WORD)) != EXECUTE_OK)
  2354.       return(status);
  2355.  
  2356.   // Are they trying to divide by zero?
  2357.   if(ea_data==0)
  2358.   {
  2359.     if((status=ProcessException(5)) != EXECUTE_OK)
  2360.       return(status);
  2361.     if(trace);
  2362.       trace_record+="{Mnemonic {Divide by Zero Exception}} ";
  2363.     return(EXECUTE_OK);
  2364.   }
  2365.  
  2366.   // Get the register number
  2367.   register_number=D0_INDEX+((opcode&0x0e00) >> 9);
  2368.  
  2369.   high_result=register_value[register_number] % ea_data;
  2370.   high_result=high_result << 16;
  2371.   low_result=register_value[register_number] / ea_data;
  2372.  
  2373.   SetRegister(register_number, high_result|(low_result&0xffff), LONG);
  2374.   SetConditionCodes(0, 0, low_result, WORD, OTHER, C_FLAG|Z_FLAG|N_FLAG);
  2375.  
  2376.   // Set the overflow flag
  2377.   if(low_result & 0xffff0000)
  2378.     register_value[SR_INDEX] |= V_FLAG;
  2379.   else
  2380.     register_value[SR_INDEX] &= ~V_FLAG;
  2381.  
  2382.   if(trace)
  2383.   {
  2384.     trace_record+="{Mnemonic {DIVU.W ";
  2385.     trace_record+=ea_description;
  2386.     trace_record+=",";
  2387.     trace_record+=register_data[register_number].name;
  2388.     trace_record+="}} ";
  2389.   }
  2390.   return(EXECUTE_OK);
  2391. }
  2392.  
  2393. ///////////////////////////////////////////////////////////////////////////////
  2394. // Execute the 'EOR' instruction
  2395. ///////////////////////////////////////////////////////////////////////////////
  2396. int m68000::ExecuteEOR(int opcode, String& trace_record, int trace)
  2397. {
  2398.   int status, size, in_register_flag;
  2399.   unsigned long ea_address, register_number;
  2400.   unsigned int result, ea_data;
  2401.   String mnemonic, ea_description;
  2402.  
  2403.   size=(opcode&0x00c0) >> 6;
  2404.  
  2405.   // Get the <ea> data address
  2406.   if((status=ComputeEffectiveAddress(ea_address, in_register_flag,
  2407.                   ea_description, opcode & 0x3f, size, trace)) != EXECUTE_OK)
  2408.   { return(status); }
  2409.  
  2410.   // Fetch the <ea> data
  2411.   if(in_register_flag)
  2412.     ea_data=register_value[ea_address];
  2413.   else
  2414.     if((status=Peek(ea_address, ea_data, size)) != EXECUTE_OK)
  2415.       return(status);
  2416.  
  2417.   // Get the register number
  2418.   register_number=D0_INDEX+((opcode&0x0e00) >> 9);
  2419.  
  2420.   result=register_value[register_number]^ea_data;
  2421.   SetConditionCodes(register_value[register_number], ea_data, result, size,
  2422.                     OTHER, V_FLAG|C_FLAG|Z_FLAG|N_FLAG);
  2423.   if(in_register_flag)
  2424.     SetRegister(ea_address, result, size);
  2425.   else
  2426.     if((status=Poke(ea_address, result, size)) != EXECUTE_OK)
  2427.       return(status);
  2428.  
  2429.   if(trace)
  2430.   {
  2431.     mnemonic+="{Mnemonic {EOR";
  2432.     if (size==BYTE)
  2433.       mnemonic+=".B ";
  2434.     else if (size==WORD)
  2435.       mnemonic+=".W ";
  2436.     else if (size==LONG)
  2437.       mnemonic+=".L ";
  2438.     mnemonic+=register_data[register_number].name;
  2439.     mnemonic+=",";
  2440.     mnemonic+=ea_description;
  2441.     mnemonic+="}} ";
  2442.     trace_record+=mnemonic;
  2443.   }
  2444.   return(EXECUTE_OK);
  2445. }
  2446.  
  2447. ///////////////////////////////////////////////////////////////////////////////
  2448. // Execute the 'EORI' instruction 
  2449. ///////////////////////////////////////////////////////////////////////////////
  2450. int m68000::ExecuteEORI(int opcode, String& trace_record, int trace)
  2451. {
  2452.   int status, size, in_register;
  2453.   unsigned long dest_addr, src_addr;
  2454.   unsigned int result, src, dest;
  2455.   String mnemonic;
  2456.  
  2457.   size=(opcode&0x00c0) >> 6;
  2458.  
  2459.   if(trace)
  2460.   {
  2461.     mnemonic+="{Mnemonic {EORI";
  2462.     if (size==BYTE)
  2463.       mnemonic+=".B ";
  2464.     else if (size==WORD)
  2465.       mnemonic+=".W ";
  2466.     else if (size==LONG)
  2467.       mnemonic+=".L ";
  2468.   }
  2469.  
  2470.   // Get the immediate data pointer
  2471.   if((status=ComputeEffectiveAddress(src_addr, in_register, mnemonic,
  2472.                     0x3c, size, trace)) != EXECUTE_OK)
  2473.   { return(status); }
  2474.  
  2475.   // Fetch the immediate data
  2476.   if((status=Peek(src_addr, src, size)) != EXECUTE_OK)
  2477.     return(status);
  2478.  
  2479.   if(trace)
  2480.     mnemonic+=",";
  2481.  
  2482.   // Get the destination data pointer
  2483.   if((status=ComputeEffectiveAddress(dest_addr, in_register, mnemonic,
  2484.                     opcode & 0x3f, size, trace)) != EXECUTE_OK)
  2485.   { return(status); }
  2486.  
  2487.   if(in_register)
  2488.   {
  2489.     dest=register_value[dest_addr];
  2490.     result=dest^src;
  2491.     SetConditionCodes(src,dest,result,size,
  2492.                       OTHER, C_FLAG|V_FLAG|Z_FLAG|N_FLAG);
  2493.     SetRegister(dest_addr,result,size);
  2494.   } 
  2495.   else
  2496.   {
  2497.     if((status=Peek(dest_addr, dest, size)) != EXECUTE_OK)
  2498.       return(status);
  2499.     result=dest^src;
  2500.     SetConditionCodes(src,dest,result,size,
  2501.                       OTHER, C_FLAG|V_FLAG|Z_FLAG|N_FLAG);
  2502.     if((status=Poke(dest_addr, result, size)) != EXECUTE_OK)
  2503.       return(status);
  2504.   }
  2505.  
  2506.   if (trace)
  2507.   {
  2508.     mnemonic+="}} ";
  2509.     trace_record+=mnemonic;
  2510.   }
  2511.   return(EXECUTE_OK);
  2512. }
  2513.  
  2514. ///////////////////////////////////////////////////////////////////////////////
  2515. // Execute the 'EORItoCCR' instruction 
  2516. ///////////////////////////////////////////////////////////////////////////////
  2517. int m68000::ExecuteEORItoCCR(int opcode, String& trace_record, int trace)
  2518. {
  2519.   int status, in_register_flag;
  2520.   unsigned long src_addr;
  2521.   unsigned int src;
  2522.   String ea_description;
  2523.  
  2524.   // Get the immediate data pointer
  2525.   if((status=ComputeEffectiveAddress(src_addr, in_register_flag, ea_description,
  2526.                 0x3c, BYTE, trace)) != EXECUTE_OK)
  2527.   { return(status); }
  2528.  
  2529.   // Fetch the immediate data
  2530.   if((status=Peek(src_addr, src, BYTE)) != EXECUTE_OK)
  2531.     return(status);
  2532.  
  2533.   SetRegister(SR_INDEX, register_value[SR_INDEX]^src, BYTE);
  2534.   if (trace)
  2535.   {
  2536.     trace_record+="{Mnemonic {EORI.B ";
  2537.     trace_record+=ea_description;
  2538.     trace_record+=",CCR}} ";
  2539.   }
  2540.   return(EXECUTE_OK);
  2541. }
  2542.  
  2543. ///////////////////////////////////////////////////////////////////////////////
  2544. // Execute the 'EORItoSR' instruction 
  2545. ///////////////////////////////////////////////////////////////////////////////
  2546. int m68000::ExecuteEORItoSR(int opcode, String& trace_record, int trace)
  2547. {
  2548.   int status, in_register_flag;
  2549.   unsigned long src_addr;
  2550.   unsigned int src;
  2551.   String ea_description;
  2552.  
  2553.   // Make sure we're in supervisor mode or trap
  2554.   if (!(register_value[SR_INDEX] & S_FLAG))
  2555.   {
  2556.     SetRegister(PC_INDEX, register_value[PC_INDEX]-2, LONG);
  2557.     if((status=ProcessException(8)) != EXECUTE_OK)
  2558.       return(status);
  2559.     if(trace);
  2560.       trace_record+="{Mnemonic {Privilege Violation Exception}} ";
  2561.     return(EXECUTE_PRIVILEGED_OK);
  2562.   }
  2563.  
  2564.   // Get the immediate data pointer
  2565.   if((status=ComputeEffectiveAddress(src_addr, in_register_flag, ea_description,
  2566.                     0x3c, WORD, trace)) != EXECUTE_OK)
  2567.   { return(status); }
  2568.  
  2569.   // Fetch the immediate data
  2570.   if((status=Peek(src_addr, src, WORD)) != EXECUTE_OK)
  2571.     return(status);
  2572.  
  2573.   SetRegister(SR_INDEX, register_value[SR_INDEX]^src , WORD);
  2574.  
  2575.   if (trace)
  2576.   {
  2577.     trace_record+="{Mnemonic {EORI.W ";
  2578.     trace_record+=ea_description;
  2579.     trace_record+=",SR}} ";
  2580.   }
  2581.   return(EXECUTE_PRIVILEGED_OK);
  2582. }
  2583.  
  2584. ///////////////////////////////////////////////////////////////////////////////
  2585. // Execute the 'EXG' instruction 
  2586. ///////////////////////////////////////////////////////////////////////////////
  2587. int m68000::ExecuteEXG(int opcode, String& trace_record, int trace)
  2588. {
  2589.   unsigned long tmp;
  2590.   unsigned int src_register,dest_register;
  2591.  
  2592.   // Get the src and dest registers numbers
  2593.   switch ((opcode&0x00f8) >> 3)
  2594.   {
  2595.     case 8:    // Data Registers
  2596.       src_register=D0_INDEX+((opcode&0x0e00) >> 9);
  2597.       dest_register=D0_INDEX+(opcode&0x0007);
  2598.       break;
  2599.     case 9:    // Address Registers
  2600.       src_register=A0_INDEX+((opcode&0x0e00) >> 9);
  2601.       dest_register=A0_INDEX+(opcode&0x0007);
  2602.       if(register_value[SR_INDEX]&S_FLAG)
  2603.       {
  2604.         if(src_register==USP_INDEX)
  2605.           src_register=SSP_INDEX;
  2606.         if(dest_register==USP_INDEX)
  2607.           dest_register=SSP_INDEX;
  2608.       }
  2609.       break;
  2610.     case 17:    // Data register and Address register
  2611.       src_register=D0_INDEX+((opcode&0x0e00) >> 9);
  2612.       dest_register=A0_INDEX+(opcode&0x0007);
  2613.       if(register_value[SR_INDEX]&S_FLAG)
  2614.       {
  2615.         if(dest_register==USP_INDEX)
  2616.           dest_register=SSP_INDEX;
  2617.       }
  2618.       break;
  2619.   }
  2620.  
  2621.   // Exchange the src and dest registers
  2622.   tmp=register_value[src_register];
  2623.   SetRegister(src_register, register_value[dest_register], LONG);
  2624.   SetRegister(dest_register, tmp, LONG);
  2625.     
  2626.   if (trace)
  2627.   {
  2628.     trace_record+="{Mnemonic {EXG.L ";
  2629.     trace_record+=register_data[src_register].name;
  2630.     trace_record+=",";
  2631.     trace_record+=register_data[dest_register].name;
  2632.     trace_record+="}} ";
  2633.   }
  2634.   return(EXECUTE_OK);
  2635. }
  2636.  
  2637. ///////////////////////////////////////////////////////////////////////////////
  2638. // Execute the 'EXT' instruction 
  2639. ///////////////////////////////////////////////////////////////////////////////
  2640. int m68000::ExecuteEXT(int opcode, String& trace_record, int trace)
  2641. {
  2642.   unsigned int register_number;
  2643.   unsigned long data;
  2644.  
  2645.   if(trace) trace_record+="{Mnemonic {EXT";
  2646.  
  2647.   // Get the data register number
  2648.   register_number=D0_INDEX+(opcode&0x0007);
  2649.   data=register_value[register_number];
  2650.  
  2651.   // Extend the data
  2652.   if(((opcode&0x01c0) >> 6) == 2)
  2653.   {
  2654.     data=SignExtend(data,BYTE);
  2655.     SetRegister(register_number, data, WORD);
  2656.     SetConditionCodes(0, 0, data, WORD, OTHER, V_FLAG|C_FLAG|Z_FLAG|N_FLAG);
  2657.     if(trace) trace_record+=".W ";
  2658.   }
  2659.   else
  2660.   {
  2661.     data=SignExtend(data,WORD);
  2662.     SetRegister(register_number, data, LONG); 
  2663.     SetConditionCodes(0, 0, data, LONG, OTHER, V_FLAG|C_FLAG|Z_FLAG|N_FLAG);
  2664.     if(trace) trace_record+=".L ";
  2665.   }
  2666.  
  2667.   if (trace)
  2668.   {
  2669.     trace_record+=register_data[register_number].name;
  2670.     trace_record+="}} ";
  2671.   }
  2672.   return(EXECUTE_OK);
  2673. }
  2674.  
  2675. ///////////////////////////////////////////////////////////////////////////////
  2676. // Execute the 'ILLEGAL' instruction 
  2677. ///////////////////////////////////////////////////////////////////////////////
  2678. int m68000::ExecuteILLEGAL(int opcode, String& trace_record, int trace)
  2679. {
  2680.   int status;
  2681.  
  2682.   // Move the PC back to the start of the illegal instruction opcode
  2683.   SetRegister(PC_INDEX, register_value[PC_INDEX]-2, LONG);
  2684.  
  2685.   // Process the illegal instruction exception
  2686.   if((status=ProcessException(4)) != EXECUTE_OK)
  2687.     return(status);
  2688.  
  2689.   if(trace)
  2690.     trace_record+="{Mnemonic {ILLEGAL}} ";
  2691.  
  2692.   return(EXECUTE_OK);
  2693. }
  2694.  
  2695. ///////////////////////////////////////////////////////////////////////////////
  2696. // Execute the 'JMP' instruction
  2697. //////////////////////////////////////////////////////////////////////////////
  2698. int m68000::ExecuteJMP(int opcode, String& trace_record, int trace)
  2699. {
  2700.   int status, in_register_flag;
  2701.   unsigned long address;
  2702.   String ea_description;
  2703.  
  2704.   // Get the effective address
  2705.   if((status=ComputeEffectiveAddress(address, in_register_flag, ea_description,
  2706.                     opcode & 0x3f, LONG, trace)) != EXECUTE_OK)
  2707.   { return(status); }
  2708.  
  2709.   SetRegister(PC_INDEX, address, LONG);
  2710.  
  2711.   if(trace)
  2712.   {
  2713.     trace_record+="{Mnemonic {JMP ";
  2714.     trace_record+=ea_description;
  2715.     trace_record+="}} ";
  2716.   }
  2717.   return(EXECUTE_OK);
  2718. }
  2719.  
  2720. ///////////////////////////////////////////////////////////////////////////////
  2721. // Execute the 'JSR' instruction
  2722. ///////////////////////////////////////////////////////////////////////////////
  2723. int m68000::ExecuteJSR(int opcode, String& trace_record, int trace)
  2724. {
  2725.   int status, in_register_flag;
  2726.   unsigned long address, stack_address;
  2727.   String ea_description;
  2728.  
  2729.   // Get the effective address
  2730.   if((status=ComputeEffectiveAddress(address, in_register_flag, ea_description,
  2731.                     opcode & 0x3f, LONG, trace)) != EXECUTE_OK)
  2732.   { return(status); }
  2733.  
  2734.   // Push the PC onto the stack
  2735.   if(register_value[SR_INDEX] & S_FLAG)
  2736.   {
  2737.     SetRegister(SSP_INDEX, register_value[SSP_INDEX]-4, LONG);
  2738.     stack_address=register_value[SSP_INDEX];
  2739.   }
  2740.   else
  2741.   {
  2742.     SetRegister(USP_INDEX, register_value[USP_INDEX]-4, LONG);
  2743.     stack_address=register_value[USP_INDEX];
  2744.   }
  2745.   if((status=Poke(stack_address,register_value[PC_INDEX],LONG)) != EXECUTE_OK)
  2746.     return(status);
  2747.  
  2748.   SetRegister(PC_INDEX, address, LONG);
  2749.  
  2750.   if(trace)
  2751.   {
  2752.     trace_record+="{Mnemonic {JSR ";
  2753.     trace_record+=ea_description;
  2754.     trace_record+="}} ";
  2755.   }
  2756.   return(EXECUTE_OK);
  2757. }
  2758.  
  2759. ///////////////////////////////////////////////////////////////////////////////
  2760. // Execute the 'LEA' instruction
  2761. ///////////////////////////////////////////////////////////////////////////////
  2762. int m68000::ExecuteLEA(int opcode, String& trace_record, int trace)
  2763. {
  2764.   int status, in_register_flag;
  2765.   unsigned long address, register_number;
  2766.   String ea_description;
  2767.  
  2768.   // Get the effective address
  2769.   if((status=ComputeEffectiveAddress(address, in_register_flag, ea_description,
  2770.                     opcode & 0x3f, LONG, trace)) != EXECUTE_OK)
  2771.   { return(status); }
  2772.  
  2773.   // Get the address register number
  2774.   register_number=A0_INDEX+((opcode&0x0e00) >> 9);
  2775.  
  2776.   // Adjust register_number if it's A7 and we're in supervisor mode
  2777.   if((register_number == USP_INDEX) && (register_value[SR_INDEX] & S_FLAG))
  2778.     register_number = SSP_INDEX;
  2779.  
  2780.   SetRegister(register_number, address, LONG);
  2781.  
  2782.   if(trace)
  2783.   {
  2784.     trace_record+="{Mnemonic {LEA.L ";
  2785.     trace_record+=ea_description;
  2786.     trace_record+=",";
  2787.     trace_record+=register_data[register_number].name;
  2788.     trace_record+="}} ";
  2789.   }
  2790.   return(EXECUTE_OK);
  2791. }
  2792.  
  2793. ///////////////////////////////////////////////////////////////////////////////
  2794. // Execute the 'LINK' instruction 
  2795. ///////////////////////////////////////////////////////////////////////////////
  2796. int m68000::ExecuteLINK(int opcode, String& trace_record, int trace)
  2797. {
  2798.   int status, in_register_flag, register_number, stack_index;
  2799.   unsigned long address;
  2800.   unsigned int displacement;
  2801.   String ea_description;
  2802.  
  2803.   // Get the displacement data pointer
  2804.   if((status=ComputeEffectiveAddress(address, in_register_flag, ea_description,
  2805.                     0x3c, WORD, trace)) != EXECUTE_OK)
  2806.   { return(status); }
  2807.  
  2808.   // Fetch the displacement data
  2809.   if((status=Peek(address, displacement, WORD)) != EXECUTE_OK)
  2810.     return(status);
  2811.   displacement=SignExtend(displacement, WORD);
  2812.  
  2813.   // Get the address register number
  2814.   register_number=A0_INDEX+(opcode&0x0007);
  2815.  
  2816.   // Adjust register_number if it's A7 and we're in supervisor mode
  2817.   if((register_number == USP_INDEX) && (register_value[SR_INDEX] & S_FLAG))
  2818.     register_number = SSP_INDEX;
  2819.  
  2820.   // Get the stack index
  2821.   if(register_value[SR_INDEX]&S_FLAG)
  2822.     stack_index=SSP_INDEX;
  2823.   else
  2824.     stack_index=USP_INDEX;
  2825.  
  2826.   // Push the address register onto the stack
  2827.   SetRegister(stack_index, register_value[stack_index]-4, LONG);
  2828.   if((status=Poke(register_value[stack_index],
  2829.        register_value[register_number], LONG)) != EXECUTE_OK)
  2830.   { return(status); }
  2831.  
  2832.   // Move the stack pointer into the address register
  2833.   SetRegister(register_number, register_value[stack_index], LONG);
  2834.  
  2835.   // Add displacement to the stack pointer
  2836.   SetRegister(stack_index, register_value[stack_index]+displacement, LONG);
  2837.  
  2838.   if(trace)
  2839.   {
  2840.     trace_record+="{Mnemonic {LINK ";
  2841.     trace_record+=register_data[register_number].name;
  2842.     trace_record+=",";
  2843.     trace_record+=ea_description;
  2844.     trace_record+="}} ";
  2845.   }
  2846.   return(EXECUTE_OK);
  2847. }
  2848.  
  2849. ///////////////////////////////////////////////////////////////////////////////
  2850. // Execute the 'LSL' instruction 
  2851. ///////////////////////////////////////////////////////////////////////////////
  2852. int m68000::ExecuteLSL(int opcode, String& trace_record, int trace)
  2853. {
  2854.   int status, size, in_register_flag, shift_count;
  2855.   unsigned long address;
  2856.   unsigned int data;
  2857.   String ea_description;
  2858.  
  2859.   size=(opcode&0x00c0) >> 6;
  2860.  
  2861.   // Check to see if this is a memory or register shift 
  2862.   if(size == 3)
  2863.   {
  2864.     size=WORD;    // Memory always shifts a word
  2865.  
  2866.     // Get the address
  2867.     if((status=ComputeEffectiveAddress(address,in_register_flag,ea_description,
  2868.                  opcode & 0x3f, size, trace)) != EXECUTE_OK)
  2869.     { return(status); }
  2870.  
  2871.     // Fetch the data
  2872.     if((status=Peek(address, data, size)) != EXECUTE_OK)
  2873.       return(status);
  2874.  
  2875.     // Shift the data to the left by one bit.
  2876.     data=data << 1;
  2877.  
  2878.     // Store the shifted data
  2879.     if((status=Poke(address, data, size)) != EXECUTE_OK)
  2880.       return(status);
  2881.  
  2882.     SetConditionCodes(0, 0, data, size,
  2883.         OTHER, N_FLAG|Z_FLAG|X_FLAG|C_FLAG|V_FLAG); 
  2884.     if(data&0x00010000)
  2885.     {
  2886.       register_value[SR_INDEX] |= C_FLAG;
  2887.       register_value[SR_INDEX] |= X_FLAG;
  2888.     }
  2889.   }
  2890.   else
  2891.   {
  2892.     // Compute the shift count
  2893.     if(opcode&32)
  2894.     {
  2895.       shift_count=register_value[D0_INDEX+((opcode&0x0e00) >> 9)] & 0x3f;
  2896.       if(trace)
  2897.         ea_description=register_data[D0_INDEX+((opcode&0x0e00) >> 9)].name;
  2898.     }
  2899.     else
  2900.     {
  2901.       if((shift_count=(opcode&0x0e00) >> 9) == 0)
  2902.         shift_count=8;
  2903.  
  2904.       if(trace)
  2905.       {
  2906.         ea_description="#$";
  2907.         ea_description+=IntToString(shift_count,1);
  2908.       }
  2909.     }
  2910.  
  2911.     if(trace)
  2912.     {
  2913.       ea_description+=",";
  2914.       ea_description+=register_data[D0_INDEX+(opcode&7)].name;
  2915.     }
  2916.  
  2917.     unsigned int carry;
  2918.     unsigned int carry_mask;
  2919.  
  2920.     // Setup masks
  2921.     if(size==BYTE)
  2922.       carry_mask=0x80;
  2923.     else if(size==WORD)
  2924.       carry_mask=0x8000;
  2925.     else
  2926.       carry_mask=0x80000000;
  2927.  
  2928.     // Perform the shift on the data
  2929.     data=register_value[D0_INDEX+(opcode&7)];
  2930.     for(int t=0;t<shift_count;++t)
  2931.     {
  2932.       carry=data & carry_mask;
  2933.       data=data << 1;
  2934.     }
  2935.  
  2936.     SetRegister(D0_INDEX+(opcode&7), data, size);
  2937.  
  2938.     SetConditionCodes(0, 0, data, size,
  2939.         OTHER, N_FLAG|Z_FLAG|X_FLAG|C_FLAG|V_FLAG); 
  2940.     if(carry)
  2941.     {
  2942.       register_value[SR_INDEX] |= C_FLAG;
  2943.       register_value[SR_INDEX] |= X_FLAG;
  2944.     }
  2945.   }
  2946.  
  2947.   if (trace)
  2948.   {
  2949.     trace_record+="{Mnemonic {LSL";
  2950.     if(size==BYTE)
  2951.       trace_record+=".B ";
  2952.     else if(size==WORD)
  2953.       trace_record+=".W ";
  2954.     else if(size==LONG)
  2955.       trace_record+=".L ";
  2956.     trace_record+=ea_description;
  2957.     trace_record+="}} ";
  2958.   }
  2959.   return(EXECUTE_OK);
  2960. }
  2961.  
  2962. ///////////////////////////////////////////////////////////////////////////////
  2963. // Execute the 'LSR' instruction 
  2964. ///////////////////////////////////////////////////////////////////////////////
  2965. int m68000::ExecuteLSR(int opcode, String& trace_record, int trace)
  2966. {
  2967.   int status, size, in_register_flag, shift_count;
  2968.   unsigned long address;
  2969.   unsigned int data;
  2970.   String ea_description;
  2971.  
  2972.   size=(opcode&0x00c0) >> 6;
  2973.  
  2974.   // Check to see if this is a memory or register shift
  2975.   if(size == 3)
  2976.   {
  2977.     size=WORD;    // Memory always shifts a word
  2978.  
  2979.     // Get the address
  2980.     if((status=ComputeEffectiveAddress(address,in_register_flag,ea_description,
  2981.                  opcode & 0x3f, size, trace)) != EXECUTE_OK)
  2982.     { return(status); }
  2983.  
  2984.     // Fetch the data
  2985.     if((status=Peek(address, data, size)) != EXECUTE_OK)
  2986.       return(status);
  2987.  
  2988.     // Set the condition codes
  2989.     SetConditionCodes(0, 0, (data >> 1) & 0x7fff, size,
  2990.         OTHER, N_FLAG|Z_FLAG|X_FLAG|C_FLAG|V_FLAG); 
  2991.     if(data & 0x0001)
  2992.     {
  2993.       register_value[SR_INDEX] |= C_FLAG;
  2994.       register_value[SR_INDEX] |= X_FLAG;
  2995.     }
  2996.  
  2997.     // Shift the data to the right by one bit.
  2998.     data=(data >> 1) & 0x7fff;
  2999.  
  3000.     // Store the shifted data
  3001.     if((status=Poke(address, data, size)) != EXECUTE_OK)
  3002.       return(status);
  3003.   }
  3004.   else
  3005.   {
  3006.     // Compute the shift count
  3007.     if(opcode&32)
  3008.     {
  3009.       shift_count=register_value[D0_INDEX+((opcode&0x0e00) >> 9)] & 0x3f;
  3010.       if(trace)
  3011.         ea_description=register_data[D0_INDEX+((opcode&0x0e00) >> 9)].name;
  3012.     }
  3013.     else
  3014.     {
  3015.       if((shift_count=(opcode&0x0e00) >> 9) == 0)
  3016.         shift_count=8;
  3017.  
  3018.       if(trace)
  3019.       {
  3020.         ea_description="#$";
  3021.         ea_description+=IntToString(shift_count,1);
  3022.       }
  3023.     }
  3024.  
  3025.     if(trace)
  3026.     {
  3027.       ea_description+=",";
  3028.       ea_description+=register_data[D0_INDEX+(opcode&7)].name;
  3029.     }
  3030.  
  3031.     unsigned int carry, clear_mask;
  3032.  
  3033.     // Setup masks
  3034.     if(size==BYTE)
  3035.       clear_mask=0x7f;
  3036.     else if(size==WORD)
  3037.       clear_mask=0x7fff;
  3038.     else
  3039.       clear_mask=0x7fffffff;
  3040.  
  3041.     // Perform the shift on the data
  3042.     data=register_value[D0_INDEX+(opcode&7)];
  3043.     for(int t=0;t<shift_count;++t)
  3044.     {
  3045.       carry=data & 0x00000001;
  3046.       data=(data >> 1) & clear_mask;
  3047.     }
  3048.  
  3049.     SetRegister(D0_INDEX+(opcode&7), data, size);
  3050.  
  3051.     SetConditionCodes(0, 0, data, size,
  3052.         OTHER, N_FLAG|Z_FLAG|X_FLAG|C_FLAG|V_FLAG); 
  3053.     if(carry)
  3054.     {
  3055.       register_value[SR_INDEX] |= C_FLAG;
  3056.       register_value[SR_INDEX] |= X_FLAG;
  3057.     }
  3058.   }
  3059.  
  3060.   if (trace)
  3061.   {
  3062.     trace_record+="{Mnemonic {LSR";
  3063.     if(size==BYTE)
  3064.       trace_record+=".B ";
  3065.     else if(size==WORD)
  3066.       trace_record+=".W ";
  3067.     else if(size==LONG)
  3068.       trace_record+=".L ";
  3069.     trace_record+=ea_description;
  3070.     trace_record+="}} ";
  3071.   }
  3072.   return(EXECUTE_OK);
  3073. }
  3074.  
  3075. ///////////////////////////////////////////////////////////////////////////////
  3076. // Execute the 'MOVE' instruction
  3077. ///////////////////////////////////////////////////////////////////////////////
  3078. int m68000::ExecuteMOVE(int opcode, String& trace_record, int trace)
  3079. {
  3080.   int status, in_register_flag, size;
  3081.   unsigned long src_address, dest_address;
  3082.   unsigned int src;
  3083.   String ea_description;
  3084.  
  3085.   switch ((opcode&0x3000)>>12)
  3086.   {
  3087.     case 1:
  3088.       size=BYTE;
  3089.       break;
  3090.     case 3:
  3091.       size=WORD;
  3092.       break;
  3093.     case 2:
  3094.       size=LONG;
  3095.       break;
  3096.   }
  3097.  
  3098.   // Get the source effective address
  3099.   if((status=ComputeEffectiveAddress(src_address, in_register_flag,
  3100.                     ea_description, opcode & 0x3f, size, trace)) != EXECUTE_OK)
  3101.   { return(status); }
  3102.  
  3103.   if(in_register_flag)
  3104.     src=register_value[src_address];
  3105.   else
  3106.     if((status=Peek(src_address, src, size)) != EXECUTE_OK)
  3107.       return(status);
  3108.  
  3109.   if(trace) ea_description+=",";
  3110.  
  3111.   // Get the destination effective address
  3112.   if((status=ComputeEffectiveAddress(dest_address, in_register_flag,
  3113.                     ea_description, ((opcode&0x01c0)>>3)|((opcode&0x0e00)>>9),
  3114.                     size, trace)) != EXECUTE_OK)
  3115.   { return(status); }
  3116.  
  3117.   if(in_register_flag)
  3118.     SetRegister(dest_address, src, size);
  3119.   else
  3120.     if((status=Poke(dest_address, src, size)) != EXECUTE_OK)
  3121.       return(status);
  3122.  
  3123.   SetConditionCodes(0, 0, src, size, OTHER,
  3124.                     N_FLAG|Z_FLAG|V_FLAG|C_FLAG);
  3125.   if(trace)
  3126.   {
  3127.     trace_record+="{Mnemonic {MOVE";
  3128.     if (size==BYTE)
  3129.       trace_record+=".B ";
  3130.     else if (size==WORD)
  3131.       trace_record+=".W ";
  3132.     else if (size==LONG)
  3133.       trace_record+=".L ";
  3134.     trace_record+=ea_description;
  3135.     trace_record+="}} ";
  3136.   }
  3137.   return(EXECUTE_OK);
  3138. }
  3139.  
  3140. ///////////////////////////////////////////////////////////////////////////////
  3141. // Execute the 'MOVEA' instruction
  3142. ///////////////////////////////////////////////////////////////////////////////
  3143. int m68000::ExecuteMOVEA(int opcode, String& trace_record, int trace)
  3144. {
  3145.   int status, in_register_flag, size;
  3146.   unsigned long src_address, dest_address;
  3147.   unsigned int src;
  3148.   String ea_description;
  3149.  
  3150.   switch ((opcode&0x3000)>>12)
  3151.   {
  3152.     case 3:
  3153.       size=WORD;
  3154.       break;
  3155.     case 2:
  3156.       size=LONG;
  3157.       break;
  3158.   }
  3159.  
  3160.   // Get the source effective address
  3161.   if((status=ComputeEffectiveAddress(src_address, in_register_flag,
  3162.                     ea_description, opcode & 0x3f, size, trace)) != EXECUTE_OK)
  3163.   { return(status); }
  3164.  
  3165.   if(in_register_flag)
  3166.     src=register_value[src_address];
  3167.   else
  3168.     if((status=Peek(src_address, src, size)) != EXECUTE_OK)
  3169.       return(status);
  3170.  
  3171.   if(size==WORD)
  3172.     src=SignExtend(src,WORD);
  3173.  
  3174.   if(trace) ea_description+=",";
  3175.  
  3176.   // Get the destination effective address
  3177.   if((status=ComputeEffectiveAddress(dest_address, in_register_flag,
  3178.                     ea_description, ((opcode&0x01c0)>>3)|((opcode&0x0e00)>>9),
  3179.                     LONG, trace)) != EXECUTE_OK)
  3180.   { return(status); }
  3181.  
  3182.   if(in_register_flag)
  3183.     SetRegister(dest_address, src, LONG);
  3184.   else
  3185.     if((status=Poke(dest_address, src, LONG)) != EXECUTE_OK)
  3186.       return(status);
  3187.  
  3188.   if(trace)
  3189.   {
  3190.     trace_record+="{Mnemonic {MOVEA";
  3191.     if (size==WORD)
  3192.       trace_record+=".W ";
  3193.     else if (size==LONG)
  3194.       trace_record+=".L ";
  3195.     trace_record+=ea_description;
  3196.     trace_record+="}} ";
  3197.   }
  3198.   return(EXECUTE_OK);
  3199. }
  3200.  
  3201. ///////////////////////////////////////////////////////////////////////////////
  3202. // Execute the 'MOVEM' instruction
  3203. ///////////////////////////////////////////////////////////////////////////////
  3204. int m68000::ExecuteMOVEM(int opcode, String& trace_record, int trace)
  3205. {
  3206.   int status, in_register_flag, size;
  3207.   unsigned long address, offset, reg;
  3208.   unsigned int list, data;
  3209.   String ea_description, mnemonic;
  3210.  
  3211.   // Determine size and offset
  3212.   if(opcode&64)
  3213.   {
  3214.     offset=4;
  3215.     size=LONG;
  3216.   }
  3217.   else
  3218.   {
  3219.     offset=2;
  3220.     size=WORD;
  3221.   }
  3222.  
  3223.   if(trace)
  3224.   {
  3225.     mnemonic+="{Mnemonic {MOVEM";
  3226.     if (size==WORD)
  3227.       mnemonic+=".W ";
  3228.     else if (size==LONG)
  3229.       mnemonic+=".L ";
  3230.   }
  3231.  
  3232.   // Get the register list mask
  3233.   if((status=Peek(register_value[PC_INDEX], list, WORD)) != EXECUTE_OK)
  3234.     return(status);
  3235.   SetRegister(PC_INDEX, register_value[PC_INDEX]+2, LONG);
  3236.  
  3237.   // Get the effective address (if this isn't predecrement)
  3238.   if((opcode&0x38)!=32)
  3239.   {
  3240.     if((status=ComputeEffectiveAddress(address, in_register_flag,
  3241.                 ea_description, opcode & 0x3f, size, trace)) != EXECUTE_OK)
  3242.     { return(status); }
  3243.   }
  3244.  
  3245.   if((opcode&0x38)==32)    // Predecrement mode
  3246.   {
  3247.     if((register_value[SR_INDEX]&S_FLAG) && ((A0_INDEX+(opcode&7))==USP_INDEX))
  3248.       reg=SSP_INDEX;
  3249.     else
  3250.       reg=A0_INDEX+(opcode&7);
  3251.     address=register_value[reg];
  3252.     if(trace)
  3253.     {
  3254.       ea_description+="-(";
  3255.       ea_description+=register_data[reg].name;
  3256.       ea_description+=")";
  3257.     }
  3258.  
  3259.     for(int t=A0_INDEX+7;t>=D0_INDEX;--t)
  3260.     {
  3261.       if(list & (1 << (A0_INDEX+7-t)))
  3262.       {
  3263.         if((register_value[SR_INDEX]&S_FLAG) && (t==USP_INDEX))
  3264.           reg=SSP_INDEX;
  3265.         else
  3266.           reg=t;
  3267.  
  3268.         address -= offset;
  3269.         if((status=Poke(address, register_value[reg], size)) != EXECUTE_OK)
  3270.           return(status);
  3271.  
  3272.         if(trace)
  3273.         {
  3274.           mnemonic+=register_data[reg].name;
  3275.           mnemonic+=" ";
  3276.         }
  3277.       }
  3278.     }
  3279.     if(trace)
  3280.     {
  3281.       mnemonic+=",";
  3282.       mnemonic+=ea_description;
  3283.     }
  3284.   }
  3285.   else    // Postincrement or Control mode
  3286.   {
  3287.     if(trace)
  3288.     {
  3289.       mnemonic+=ea_description;
  3290.       mnemonic+=",";
  3291.     }
  3292.     for(int t=D0_INDEX;t<=A0_INDEX+7;++t)
  3293.     {
  3294.       if(list & (1 << (t-D0_INDEX)))
  3295.       {
  3296.         if((register_value[SR_INDEX]&S_FLAG) && (t==USP_INDEX))
  3297.           reg=SSP_INDEX;
  3298.         else
  3299.           reg=t;
  3300.  
  3301.         if(opcode&1024)
  3302.         {
  3303.           if((status=Peek(address, data, size)) != EXECUTE_OK)
  3304.             return(status);
  3305.           SetRegister(reg, data, size);
  3306.         }
  3307.         else
  3308.         {
  3309.           if((status=Poke(address, register_value[reg], size)) != EXECUTE_OK)
  3310.             return(status);
  3311.         }
  3312.         address += offset;
  3313.  
  3314.         if(trace)
  3315.         {
  3316.           mnemonic+=register_data[reg].name;
  3317.           mnemonic+=" ";
  3318.         }
  3319.       }
  3320.     }
  3321.   }
  3322.  
  3323.   if(((opcode&0x38)==32) || ((opcode&0x38)==24))
  3324.   {
  3325.     if((register_value[SR_INDEX]&S_FLAG) && ((opcode&7)==7))
  3326.       SetRegister(SSP_INDEX, address, LONG);
  3327.     else
  3328.       SetRegister(A0_INDEX+(opcode&7), address, LONG);
  3329.   }
  3330.  
  3331.   if(trace)
  3332.   {
  3333.     mnemonic+="}} ";
  3334.     trace_record+=mnemonic;
  3335.   }
  3336.   return(EXECUTE_OK);
  3337. }
  3338.  
  3339. ///////////////////////////////////////////////////////////////////////////////
  3340. // Execute the '' instruction 
  3341. ///////////////////////////////////////////////////////////////////////////////
  3342. int m68000::ExecuteMOVEP(int opcode, String& trace_record, int trace)
  3343. {
  3344.   return(ExecuteInvalid(opcode, trace_record, trace));
  3345. }
  3346.  
  3347. ///////////////////////////////////////////////////////////////////////////////
  3348. // Execute the 'MOVEQ' instruction
  3349. ///////////////////////////////////////////////////////////////////////////////
  3350. int m68000::ExecuteMOVEQ(int opcode, String& trace_record, int trace)
  3351. {
  3352.   unsigned long register_number;
  3353.   unsigned int data;
  3354.  
  3355.   // Get the destination data register number
  3356.   register_number=D0_INDEX+(opcode & 0x0e00) >> 9;
  3357.  
  3358.   // Get the immediate data
  3359.   data=SignExtend((opcode & 0xff), BYTE);
  3360.  
  3361.   SetConditionCodes(0, 0, data, LONG, OTHER, C_FLAG|V_FLAG|Z_FLAG|N_FLAG);
  3362.   SetRegister(register_number, data, LONG);
  3363.  
  3364.   if (trace)
  3365.   {
  3366.     trace_record+="{Mnemonic {MOVEQ.L #$";
  3367.     trace_record+=IntToString(data,2);
  3368.     trace_record+=",";
  3369.     trace_record+=register_data[register_number].name;
  3370.     trace_record+="}} ";
  3371.   }
  3372.   return(EXECUTE_OK);
  3373. }
  3374.  
  3375. ///////////////////////////////////////////////////////////////////////////////
  3376. // Execute the 'MOVEfromSR' instruction 
  3377. ///////////////////////////////////////////////////////////////////////////////
  3378. int m68000::ExecuteMOVEfromSR(int opcode, String& trace_record, int trace)
  3379. {
  3380.   int status, in_register;
  3381.   unsigned long address;
  3382.   String ea_description;
  3383.  
  3384.   // Get the destination data pointer
  3385.   if((status=ComputeEffectiveAddress(address, in_register, ea_description,
  3386.                  opcode & 0x3f, WORD, trace)) != EXECUTE_OK)
  3387.   { return(status); }
  3388.  
  3389.   if(in_register)
  3390.     SetRegister(address, register_value[SR_INDEX], WORD);
  3391.   else
  3392.     if((status=Poke(address, register_value[SR_INDEX], WORD)) != EXECUTE_OK)
  3393.       return(status);
  3394.  
  3395.   if (trace)
  3396.   {
  3397.     trace_record+="{Mnemonic {MOVE.W SR,";
  3398.     trace_record+=ea_description;
  3399.     trace_record+="}} ";
  3400.   }
  3401.   return(EXECUTE_OK);
  3402. }
  3403.  
  3404. ///////////////////////////////////////////////////////////////////////////////
  3405. // Execute the 'MOVEUSP' instruction 
  3406. ///////////////////////////////////////////////////////////////////////////////
  3407. int m68000::ExecuteMOVEUSP(int opcode, String& trace_record, int trace)
  3408. {
  3409.   int status, register_number;
  3410.   String ea_description;
  3411.  
  3412.   // Make sure we're in supervisor mode or trap
  3413.   if (!(register_value[SR_INDEX] & S_FLAG))
  3414.   {
  3415.     SetRegister(PC_INDEX, register_value[PC_INDEX]-2, LONG);
  3416.     if((status=ProcessException(8)) != EXECUTE_OK)
  3417.       return(status);
  3418.     if(trace);
  3419.       trace_record+="{Mnemonic {Privilege Violation Exception}} ";
  3420.     return(EXECUTE_PRIVILEGED_OK);
  3421.   }
  3422.  
  3423.   // Get the address register index
  3424.   if((opcode&7) == 7)
  3425.     register_number=SSP_INDEX;
  3426.   else 
  3427.     register_number=A0_INDEX+(opcode&7);
  3428.  
  3429.   // Move from or to the USP
  3430.   if(opcode & 8)
  3431.   {
  3432.     SetRegister(register_number, register_value[USP_INDEX], LONG);
  3433.     if(trace)
  3434.     {
  3435.       ea_description="USP,";
  3436.       ea_description+=register_data[register_number].name;
  3437.     }
  3438.   } 
  3439.   else
  3440.   {
  3441.     SetRegister(USP_INDEX, register_value[register_number], LONG);
  3442.     if(trace)
  3443.     {
  3444.       ea_description=register_data[register_number].name;
  3445.       ea_description+=",USP";
  3446.     }
  3447.   }
  3448.  
  3449.   if(trace)
  3450.   {
  3451.     trace_record+="{Mnemonic {MOVE.L ";
  3452.     trace_record+=ea_description;
  3453.     trace_record+="}} ";
  3454.   }
  3455.   return(EXECUTE_PRIVILEGED_OK);
  3456. }
  3457.  
  3458. ///////////////////////////////////////////////////////////////////////////////
  3459. // Execute the 'MOVEtoCCR' instruction 
  3460. ///////////////////////////////////////////////////////////////////////////////
  3461. int m68000::ExecuteMOVEtoCCR(int opcode, String& trace_record, int trace)
  3462. {
  3463.   int status, in_register;
  3464.   unsigned long address;
  3465.   unsigned int data;
  3466.   String ea_description;
  3467.  
  3468.   // Get the destination data pointer
  3469.   if((status=ComputeEffectiveAddress(address, in_register, ea_description,
  3470.                  opcode & 0x3f, WORD, trace)) != EXECUTE_OK)
  3471.   { return(status); }
  3472.  
  3473.   if(in_register)
  3474.     data=register_value[address];
  3475.   else
  3476.     if((status=Peek(address, data, WORD)) != EXECUTE_OK)
  3477.       return(status);
  3478.  
  3479.   SetRegister(SR_INDEX, data, BYTE);
  3480.  
  3481.   if (trace)
  3482.   {
  3483.     trace_record+="{Mnemonic {MOVE.W ";
  3484.     trace_record+=ea_description;
  3485.     trace_record+=",CCR}} ";
  3486.   }
  3487.   return(EXECUTE_OK);
  3488. }
  3489.  
  3490. ///////////////////////////////////////////////////////////////////////////////
  3491. // Execute the 'MOVEtoSR' instruction 
  3492. ///////////////////////////////////////////////////////////////////////////////
  3493. int m68000::ExecuteMOVEtoSR(int opcode, String& trace_record, int trace)
  3494. {
  3495.   int status, in_register;
  3496.   unsigned long address;
  3497.   unsigned int data;
  3498.   String ea_description;
  3499.  
  3500.   // Make sure we're in supervisor mode or trap
  3501.   if (!(register_value[SR_INDEX] & S_FLAG))
  3502.   {
  3503.     SetRegister(PC_INDEX, register_value[PC_INDEX]-2, LONG);
  3504.     if((status=ProcessException(8)) != EXECUTE_OK)
  3505.       return(status);
  3506.     if(trace);
  3507.       trace_record+="{Mnemonic {Privilege Violation Exception}} ";
  3508.     return(EXECUTE_PRIVILEGED_OK);
  3509.   }
  3510.  
  3511.   // Get the destination data pointer
  3512.   if((status=ComputeEffectiveAddress(address, in_register, ea_description,
  3513.                  opcode & 0x3f, WORD, trace)) != EXECUTE_OK)
  3514.   { return(status); }
  3515.  
  3516.   if(in_register)
  3517.     data=register_value[address];
  3518.   else
  3519.     if((status=Peek(address, data, WORD)) != EXECUTE_OK)
  3520.       return(status);
  3521.  
  3522.   SetRegister(SR_INDEX, data, WORD);
  3523.  
  3524.   if (trace)
  3525.   {
  3526.     trace_record+="{Mnemonic {MOVE.W ";
  3527.     trace_record+=ea_description;
  3528.     trace_record+=",SR}} ";
  3529.   }
  3530.   return(EXECUTE_PRIVILEGED_OK);
  3531. }
  3532.  
  3533. ///////////////////////////////////////////////////////////////////////////////
  3534. // Execute the 'MULS' instruction 
  3535. ///////////////////////////////////////////////////////////////////////////////
  3536. int m68000::ExecuteMULS(int opcode, String& trace_record, int trace)
  3537. {
  3538.   int status, in_register_flag;
  3539.   unsigned long ea_address, register_number;
  3540.   unsigned int ea_data;
  3541.   int result, data;
  3542.   String ea_description;
  3543.  
  3544.   // Get the <ea> data address
  3545.   if((status=ComputeEffectiveAddress(ea_address, in_register_flag,
  3546.                  ea_description, opcode & 0x3f, WORD, trace)) != EXECUTE_OK)
  3547.   { return(status); }
  3548.  
  3549.   // Fetch the <ea> data
  3550.   if(in_register_flag)
  3551.     ea_data=register_value[ea_address];
  3552.   else
  3553.     if((status=Peek(ea_address, ea_data, WORD)) != EXECUTE_OK)
  3554.       return(status);
  3555.  
  3556.   // Get the register number
  3557.   register_number=D0_INDEX+((opcode&0x0e00) >> 9);
  3558.   data=register_value[register_number];
  3559.  
  3560.   // Sign extend operands
  3561.   data=SignExtend(data,WORD);
  3562.   ea_data=SignExtend(ea_data,WORD);
  3563.  
  3564.   result=data*ea_data;
  3565.   SetConditionCodes(0, 0, result, LONG, OTHER, V_FLAG|C_FLAG|Z_FLAG|N_FLAG);
  3566.   SetRegister(register_number, result, LONG);
  3567.  
  3568.   if(trace)
  3569.   {
  3570.     trace_record+="{Mnemonic {MULS.W ";
  3571.     trace_record+=ea_description;
  3572.     trace_record+=",";
  3573.     trace_record+=register_data[register_number].name;
  3574.     trace_record+="}} ";
  3575.   }
  3576.   return(EXECUTE_OK);
  3577. }
  3578.  
  3579. ///////////////////////////////////////////////////////////////////////////////
  3580. // Execute the 'MULU' instruction 
  3581. ///////////////////////////////////////////////////////////////////////////////
  3582. int m68000::ExecuteMULU(int opcode, String& trace_record, int trace)
  3583. {
  3584.   int status, in_register_flag;
  3585.   unsigned long ea_address, register_number;
  3586.   unsigned int result, ea_data;
  3587.   String ea_description;
  3588.  
  3589.   // Get the <ea> data address
  3590.   if((status=ComputeEffectiveAddress(ea_address, in_register_flag,
  3591.                  ea_description, opcode & 0x3f, WORD, trace)) != EXECUTE_OK)
  3592.   { return(status); }
  3593.  
  3594.   // Fetch the <ea> data
  3595.   if(in_register_flag)
  3596.     ea_data=register_value[ea_address]&0xffff;
  3597.   else
  3598.     if((status=Peek(ea_address, ea_data, WORD)) != EXECUTE_OK)
  3599.       return(status);
  3600.  
  3601.   // Get the register number
  3602.   register_number=D0_INDEX+((opcode&0x0e00) >> 9);
  3603.  
  3604.   result=(register_value[register_number]&0xffff)*ea_data;
  3605.   SetConditionCodes(0, 0, result, LONG, OTHER, V_FLAG|C_FLAG|Z_FLAG|N_FLAG);
  3606.   SetRegister(register_number, result, LONG);
  3607.  
  3608.   if(trace)
  3609.   {
  3610.     trace_record+="{Mnemonic {MULU.W ";
  3611.     trace_record+=ea_description;
  3612.     trace_record+=",";
  3613.     trace_record+=register_data[register_number].name;
  3614.     trace_record+="}} ";
  3615.   }
  3616.   return(EXECUTE_OK);
  3617. }
  3618.  
  3619. ///////////////////////////////////////////////////////////////////////////////
  3620. // Execute the '' instruction 
  3621. ///////////////////////////////////////////////////////////////////////////////
  3622. int m68000::ExecuteNBCD(int opcode, String& trace_record, int trace)
  3623. {
  3624.   return(ExecuteInvalid(opcode, trace_record, trace));
  3625. }
  3626.  
  3627. ///////////////////////////////////////////////////////////////////////////////
  3628. // Execute the 'NEG' instruction 
  3629. ///////////////////////////////////////////////////////////////////////////////
  3630. int m68000::ExecuteNEG(int opcode, String& trace_record, int trace)
  3631. {
  3632.   int status, size, in_register_flag;
  3633.   unsigned long address;
  3634.   unsigned int data, result;
  3635.   String ea_description;
  3636.  
  3637.   size=((opcode&0x00c0) >> 6);
  3638.  
  3639.   // Get the effective address
  3640.   if((status=ComputeEffectiveAddress(address, in_register_flag, ea_description,
  3641.                     opcode & 0x3f, size, trace)) != EXECUTE_OK)
  3642.   { return(status); }
  3643.  
  3644.   // Fetch the data
  3645.   if(in_register_flag)
  3646.     data=register_value[address];
  3647.   else
  3648.     if((status=Peek(address, data, size)) != EXECUTE_OK)
  3649.       return(status);
  3650.  
  3651.   data = SignExtend(data, size);
  3652.   result = 0-data;
  3653.   SetConditionCodes(data, 0, result, size,
  3654.                     SUBTRACTION, C_FLAG|X_FLAG|V_FLAG|Z_FLAG|N_FLAG);
  3655.  
  3656.   // Store the result  
  3657.   if(in_register_flag)
  3658.     SetRegister(address, result, size);
  3659.   else
  3660.     if((status=Poke(address, result, size)) != EXECUTE_OK)
  3661.       return(status);
  3662.  
  3663.   if(trace)
  3664.   {
  3665.     trace_record+="{Mnemonic {NEG";
  3666.     if (size==BYTE)
  3667.       trace_record+=".B ";
  3668.     else if (size==WORD)
  3669.       trace_record+=".W ";
  3670.     else if (size==LONG)
  3671.       trace_record+=".L ";
  3672.     trace_record+=ea_description;
  3673.     trace_record+="}} ";
  3674.   }
  3675.   return(EXECUTE_OK);
  3676. }
  3677.  
  3678. ///////////////////////////////////////////////////////////////////////////////
  3679. // Execute the 'NEGX' instruction 
  3680. ///////////////////////////////////////////////////////////////////////////////
  3681. int m68000::ExecuteNEGX(int opcode, String& trace_record, int trace)
  3682. {
  3683.   int status, size, in_register_flag;
  3684.   unsigned long address;
  3685.   unsigned int data, result;
  3686.   String ea_description;
  3687.  
  3688.   size=((opcode&0x00c0) >> 6);
  3689.  
  3690.   // Get the effective address
  3691.   if((status=ComputeEffectiveAddress(address, in_register_flag, ea_description,
  3692.                  opcode & 0x3f, size, trace)) != EXECUTE_OK)
  3693.   { return(status); }
  3694.  
  3695.   // Fetch the data
  3696.   if(in_register_flag)
  3697.     data=register_value[address];
  3698.   else
  3699.     if((status=Peek(address, data, size)) != EXECUTE_OK)
  3700.       return(status);
  3701.  
  3702.   data = SignExtend(data, size);
  3703.  
  3704.   if(register_value[SR_INDEX] & X_FLAG)
  3705.     result=0-data-1;
  3706.   else
  3707.     result=0-data;
  3708.  
  3709.   SetConditionCodes(data, 0, result, size,
  3710.                     SUBTRACTION, C_FLAG|X_FLAG|V_FLAG|N_FLAG);
  3711.   if (size==BYTE)
  3712.     result=result&0xff;
  3713.   else if (size==WORD)
  3714.     result=result&0xffff;
  3715.   else if (size==LONG)
  3716.     result=result&0xffffffff;
  3717.  
  3718.   if(result)
  3719.     register_value[SR_INDEX] &= ~Z_FLAG;
  3720.  
  3721.   // Store the result  
  3722.   if(in_register_flag)
  3723.     SetRegister(address, result, size);
  3724.   else
  3725.     if((status=Poke(address, result, size)) != EXECUTE_OK)
  3726.       return(status);
  3727.  
  3728.   if(trace)
  3729.   {
  3730.     trace_record+="{Mnemonic {NEGX";
  3731.     if (size==BYTE)
  3732.       trace_record+=".B ";
  3733.     else if (size==WORD)
  3734.       trace_record+=".W ";
  3735.     else if (size==LONG)
  3736.       trace_record+=".L ";
  3737.     trace_record+=ea_description;
  3738.     trace_record+="}} ";
  3739.   }
  3740.   return(EXECUTE_OK);
  3741. }
  3742.  
  3743. ///////////////////////////////////////////////////////////////////////////////
  3744. // Execute the 'NOP' instruction  (An instruction I like :-)
  3745. ///////////////////////////////////////////////////////////////////////////////
  3746. int m68000::ExecuteNOP(int opcode, String& trace_record, int trace)
  3747. {
  3748.   if(trace)
  3749.     trace_record+="{Mnemonic {NOP}}";
  3750.  
  3751.   return(EXECUTE_OK);
  3752. }
  3753.  
  3754. ///////////////////////////////////////////////////////////////////////////////
  3755. // Execute the 'NOT' instruction 
  3756. ///////////////////////////////////////////////////////////////////////////////
  3757. int m68000::ExecuteNOT(int opcode, String& trace_record, int trace)
  3758. {
  3759.   int status, size, in_register_flag;
  3760.   unsigned long address;
  3761.   unsigned int data, result;
  3762.   String ea_description;
  3763.  
  3764.   size=((opcode&0x00c0) >> 6);
  3765.  
  3766.   // Get the effective address
  3767.   if((status=ComputeEffectiveAddress(address, in_register_flag, ea_description,
  3768.                     opcode & 0x3f, size, trace)) != EXECUTE_OK)
  3769.   { return(status); }
  3770.  
  3771.   // Fetch the data
  3772.   if(in_register_flag)
  3773.     data=register_value[address];
  3774.   else
  3775.     if((status=Peek(address, data, size)) != EXECUTE_OK)
  3776.       return(status);
  3777.  
  3778.   result = ~data;
  3779.   SetConditionCodes(data, 0, result, size,
  3780.                     OTHER, C_FLAG|V_FLAG|Z_FLAG|N_FLAG);
  3781.  
  3782.   // Store the result  
  3783.   if(in_register_flag)
  3784.     SetRegister(address, result, size);
  3785.   else
  3786.     if((status=Poke(address, result, size)) != EXECUTE_OK)
  3787.       return(status);
  3788.  
  3789.   if(trace)
  3790.   {
  3791.     trace_record+="{Mnemonic {NOT";
  3792.     if (size==BYTE)
  3793.       trace_record+=".B ";
  3794.     else if (size==WORD)
  3795.       trace_record+=".W ";
  3796.     else if (size==LONG)
  3797.       trace_record+=".L ";
  3798.     trace_record+=ea_description;
  3799.     trace_record+="}} ";
  3800.   }
  3801.   return(EXECUTE_OK);
  3802. }
  3803.  
  3804. ///////////////////////////////////////////////////////////////////////////////
  3805. // Execute the 'OR' instruction 
  3806. ///////////////////////////////////////////////////////////////////////////////
  3807. int m68000::ExecuteOR(int opcode, String& trace_record, int trace)
  3808. {
  3809.   int status, size, in_register_flag;
  3810.   unsigned long ea_address, register_number;
  3811.   unsigned int result, ea_data;
  3812.   String mnemonic, ea_description;
  3813.  
  3814.   size=(opcode&0x00c0) >> 6;
  3815.  
  3816.   // Get the <ea> data address
  3817.   if((status=ComputeEffectiveAddress(ea_address, in_register_flag,
  3818.                   ea_description, opcode & 0x3f, size, trace)) != EXECUTE_OK)
  3819.   { return(status); }
  3820.  
  3821.   // Fetch the <ea> data 
  3822.   if(in_register_flag)
  3823.     ea_data=register_value[ea_address];
  3824.   else
  3825.     if((status=Peek(ea_address, ea_data, size)) != EXECUTE_OK)
  3826.       return(status);
  3827.  
  3828.   // Get the register number
  3829.   register_number=D0_INDEX+((opcode&0x0e00) >> 9);
  3830.  
  3831.   if(trace)
  3832.   {
  3833.     mnemonic+="{Mnemonic {OR";
  3834.     if (size==BYTE)
  3835.       mnemonic+=".B ";
  3836.     else if (size==WORD)
  3837.       mnemonic+=".W ";
  3838.     else if (size==LONG)
  3839.       mnemonic+=".L ";
  3840.   }
  3841.  
  3842.   if(opcode & 0x0100)    // <Dn> | <ea> -> <ea>
  3843.   {
  3844.     if(trace)
  3845.     {
  3846.       mnemonic+=register_data[register_number].name;
  3847.       mnemonic+=",";
  3848.       mnemonic+=ea_description;
  3849.     }
  3850.     result=register_value[register_number]|ea_data;
  3851.     SetConditionCodes(register_value[register_number], ea_data, result, size,
  3852.                       OTHER, V_FLAG|C_FLAG|Z_FLAG|N_FLAG);
  3853.     if((status=Poke(ea_address, result, size)) != EXECUTE_OK)
  3854.       return(status);
  3855.   }
  3856.   else                   // <ea> | <Dn> -> <Dn>
  3857.   {
  3858.     if(trace)
  3859.     {
  3860.       mnemonic+=ea_description;
  3861.       mnemonic+=",";
  3862.       mnemonic+=register_data[register_number].name;
  3863.     }
  3864.     result=ea_data|register_value[register_number];
  3865.     SetConditionCodes(ea_data, register_value[register_number], result, size,
  3866.                       OTHER, V_FLAG|C_FLAG|Z_FLAG|N_FLAG);
  3867.     SetRegister(register_number, result, size);
  3868.   }
  3869.  
  3870.   if(trace)
  3871.   {
  3872.     mnemonic+="}} ";
  3873.     trace_record+=mnemonic;
  3874.   }
  3875.   return(EXECUTE_OK);
  3876. }
  3877.  
  3878. ///////////////////////////////////////////////////////////////////////////////
  3879. // Execute the 'ORI' instruction 
  3880. ///////////////////////////////////////////////////////////////////////////////
  3881. int m68000::ExecuteORI(int opcode, String& trace_record, int trace)
  3882. {
  3883.   int status, size, in_register;
  3884.   unsigned long dest_addr, src_addr;
  3885.   unsigned int result, src, dest;
  3886.   String mnemonic;
  3887.  
  3888.   size=(opcode&0x00c0) >> 6;
  3889.  
  3890.   if(trace)
  3891.   {
  3892.     mnemonic+="{Mnemonic {ORI";
  3893.     if (size==BYTE)
  3894.       mnemonic+=".B ";
  3895.     else if (size==WORD)
  3896.       mnemonic+=".W ";
  3897.     else if (size==LONG)
  3898.       mnemonic+=".L ";
  3899.   }
  3900.  
  3901.   // Get the immediate data pointer
  3902.   if((status=ComputeEffectiveAddress(src_addr, in_register, mnemonic,
  3903.                     0x3c, size, trace)) != EXECUTE_OK)
  3904.   { return(status); }
  3905.  
  3906.   // Fetch the immediate data
  3907.   if((status=Peek(src_addr, src, size)) != EXECUTE_OK)
  3908.     return(status);
  3909.  
  3910.   if(trace)
  3911.     mnemonic+=",";
  3912.  
  3913.   // Get the destination data pointer
  3914.   if((status=ComputeEffectiveAddress(dest_addr, in_register, mnemonic,
  3915.                     opcode & 0x3f, size, trace)) != EXECUTE_OK)
  3916.   {
  3917.     return(status);
  3918.   }
  3919.  
  3920.   if(in_register)
  3921.   {
  3922.     dest=register_value[dest_addr];
  3923.     result=dest|src;
  3924.     SetConditionCodes(src,dest,result,size,
  3925.                       OTHER, C_FLAG|V_FLAG|Z_FLAG|N_FLAG);
  3926.     SetRegister(dest_addr,result,size);
  3927.   } 
  3928.   else
  3929.   {
  3930.     if((status=Peek(dest_addr, dest, size)) != EXECUTE_OK)
  3931.       return(status);
  3932.     result=dest|src;
  3933.     SetConditionCodes(src,dest,result,size, 
  3934.                       OTHER, C_FLAG|V_FLAG|Z_FLAG|N_FLAG);
  3935.     if((status=Poke(dest_addr, result, size)) != EXECUTE_OK)
  3936.       return(status);
  3937.   }
  3938.  
  3939.   if (trace)
  3940.   {
  3941.     mnemonic+="}} ";
  3942.     trace_record+=mnemonic;
  3943.   }
  3944.   return(EXECUTE_OK);
  3945. }
  3946.  
  3947. ///////////////////////////////////////////////////////////////////////////////
  3948. // Execute the 'ORItoCCR' instruction 
  3949. ///////////////////////////////////////////////////////////////////////////////
  3950. int m68000::ExecuteORItoCCR(int opcode, String& trace_record, int trace)
  3951. {
  3952.   int status, in_register_flag;
  3953.   unsigned long src_addr;
  3954.   unsigned int src;
  3955.   String mnemonic;
  3956.  
  3957.   if(trace)
  3958.     mnemonic+="{Mnemonic {ORI.B ";
  3959.  
  3960.   // Get the immediate data pointer
  3961.   if((status=ComputeEffectiveAddress(src_addr, in_register_flag, mnemonic,
  3962.                     0x3c, BYTE, trace)) != EXECUTE_OK)
  3963.   { return(status); }
  3964.  
  3965.   // Fetch the immediate data
  3966.   if((status=Peek(src_addr, src, BYTE)) != EXECUTE_OK)
  3967.     return(status);
  3968.  
  3969.   SetRegister(SR_INDEX, register_value[SR_INDEX]|src, BYTE);
  3970.   if (trace)
  3971.   {
  3972.     mnemonic+=",CCR}} ";
  3973.     trace_record+=mnemonic;
  3974.   }
  3975.   return(EXECUTE_OK);
  3976. }
  3977.  
  3978. ///////////////////////////////////////////////////////////////////////////////
  3979. // Execute the 'ORItoSR' instruction 
  3980. ///////////////////////////////////////////////////////////////////////////////
  3981. int m68000::ExecuteORItoSR(int opcode, String& trace_record, int trace)
  3982. {
  3983.   int status, in_register_flag;
  3984.   unsigned long src_addr;
  3985.   unsigned int src;
  3986.   String mnemonic;
  3987.  
  3988.   // Make sure we're in supervisor mode or trap
  3989.   if (!(register_value[SR_INDEX] & S_FLAG))
  3990.   {
  3991.     SetRegister(PC_INDEX, register_value[PC_INDEX]-2, LONG);
  3992.     if((status=ProcessException(8)) != EXECUTE_OK)
  3993.       return(status);
  3994.     if(trace);
  3995.       trace_record+="{Mnemonic {Privilege Violation Exception}} ";
  3996.     return(EXECUTE_PRIVILEGED_OK);
  3997.   }
  3998.  
  3999.   if(trace)
  4000.     mnemonic+="{Mnemonic {ORI.W ";
  4001.  
  4002.   // Get the immediate data pointer
  4003.   if((status=ComputeEffectiveAddress(src_addr, in_register_flag, mnemonic,
  4004.                     0x3c, WORD, trace)) != EXECUTE_OK)
  4005.   { return(status); }
  4006.  
  4007.   // Fetch the immediate data
  4008.   if((status=Peek(src_addr, src, WORD)) != EXECUTE_OK)
  4009.     return(status);
  4010.  
  4011.   SetRegister(SR_INDEX, register_value[SR_INDEX]|src, WORD);
  4012.  
  4013.   if (trace)
  4014.   {
  4015.     mnemonic+=",SR}} ";
  4016.     trace_record+=mnemonic;
  4017.   }
  4018.   return(EXECUTE_PRIVILEGED_OK);
  4019. }
  4020.  
  4021. ///////////////////////////////////////////////////////////////////////////////
  4022. // Execute the 'PEA' instruction 
  4023. ///////////////////////////////////////////////////////////////////////////////
  4024. int m68000::ExecutePEA(int opcode, String& trace_record, int trace)
  4025. {
  4026.   int status, in_register_flag, stack_index;
  4027.   unsigned long address;
  4028.   String ea_description;
  4029.  
  4030.   // Get the effective address
  4031.   if((status=ComputeEffectiveAddress(address, in_register_flag, ea_description,
  4032.                  opcode & 0x3f, LONG, trace)) != EXECUTE_OK)
  4033.   { return(status); }
  4034.  
  4035.   // Get the stack pointer index
  4036.   if(register_value[SR_INDEX]&S_FLAG)
  4037.     stack_index=SSP_INDEX;
  4038.   else
  4039.     stack_index=USP_INDEX;
  4040.  
  4041.   // Push the effective address onto the stack
  4042.   SetRegister(stack_index, register_value[stack_index]-4, LONG);
  4043.   if((status=Poke(register_value[stack_index], address, LONG)) != EXECUTE_OK)
  4044.     return(status);
  4045.  
  4046.   if(trace)
  4047.   {
  4048.     trace_record+="{Mnemonic {PEA.L ";
  4049.     trace_record+=ea_description;
  4050.     trace_record+="}} ";
  4051.   }
  4052.   return(EXECUTE_OK);
  4053. }
  4054.  
  4055. ///////////////////////////////////////////////////////////////////////////////
  4056. // Execute the 'RESET' instruction 
  4057. ///////////////////////////////////////////////////////////////////////////////
  4058. int m68000::ExecuteRESET(int opcode, String& trace_record, int trace)
  4059. {
  4060.   int status;
  4061.  
  4062.   // Make sure we're in supervisor mode or trap
  4063.   if (!(register_value[SR_INDEX] & S_FLAG))
  4064.   {
  4065.     SetRegister(PC_INDEX, register_value[PC_INDEX]-2, LONG);
  4066.     if((status=ProcessException(8)) != EXECUTE_OK)
  4067.       return(status);
  4068.     if(trace);
  4069.       trace_record+="{Mnemonic {Privilege Violation Exception}} ";
  4070.     return(EXECUTE_PRIVILEGED_OK);
  4071.   }
  4072.  
  4073.   // Tell the AddressSpace to reset all of the attached devices
  4074.   address_space->Reset();
  4075.  
  4076.   if(trace)
  4077.     trace_record+="{Mnemonic {RESET}} ";
  4078.     
  4079.   return(EXECUTE_PRIVILEGED_OK);
  4080. }
  4081.  
  4082. ///////////////////////////////////////////////////////////////////////////////
  4083. // Execute the 'ROL' instruction 
  4084. ///////////////////////////////////////////////////////////////////////////////
  4085. int m68000::ExecuteROL(int opcode, String& trace_record, int trace)
  4086. {
  4087.   int status, size, in_register_flag, shift_count;
  4088.   unsigned long address;
  4089.   unsigned int data;
  4090.   String ea_description;
  4091.  
  4092.   size=(opcode&0x00c0) >> 6;
  4093.  
  4094.   // Check to see if this is a memory or register rotate
  4095.   if(size == 3)
  4096.   {
  4097.     size=WORD;    // Memory always rotates a word
  4098.  
  4099.     // Get the address
  4100.     if((status=ComputeEffectiveAddress(address,in_register_flag,ea_description,
  4101.                  opcode & 0x3f, size, trace)) != EXECUTE_OK)
  4102.     { return(status); }
  4103.  
  4104.     // Fetch the data
  4105.     if((status=Peek(address, data, size)) != EXECUTE_OK)
  4106.       return(status);
  4107.  
  4108.     // Rotate the data to the left by one bit.
  4109.     if(data&0x8000)
  4110.       data=(data << 1) | 0x0001;
  4111.     else
  4112.       data=(data << 1);
  4113.  
  4114.     // Store the shifted data
  4115.     if((status=Poke(address, data, size)) != EXECUTE_OK)
  4116.       return(status);
  4117.  
  4118.     SetConditionCodes(0, 0, data, size, OTHER, N_FLAG|Z_FLAG|C_FLAG|V_FLAG); 
  4119.     if(data&0x0001)
  4120.       register_value[SR_INDEX] |= C_FLAG;
  4121.   }
  4122.   else
  4123.   {
  4124.     // Compute the shift count
  4125.     if(opcode&32)
  4126.     {
  4127.       shift_count=register_value[D0_INDEX+((opcode&0x0e00) >> 9)] & 0x3f;
  4128.       if(trace)
  4129.         ea_description=register_data[D0_INDEX+((opcode&0x0e00) >> 9)].name;
  4130.     }
  4131.     else
  4132.     {
  4133.       if((shift_count=(opcode&0x0e00) >> 9) == 0)
  4134.         shift_count=8;
  4135.  
  4136.       if(trace)
  4137.       {
  4138.         ea_description="#$";
  4139.         ea_description+=IntToString(shift_count,1);
  4140.       }
  4141.     }
  4142.  
  4143.     if(trace)
  4144.     {
  4145.       ea_description+=",";
  4146.       ea_description+=register_data[D0_INDEX+(opcode&7)].name;
  4147.     }
  4148.  
  4149.     unsigned int msb;
  4150.  
  4151.     // Setup MSB  
  4152.     if(size==BYTE)
  4153.       msb=0x80;
  4154.     else if(size==WORD)
  4155.       msb=0x8000;
  4156.     else
  4157.       msb=0x80000000;
  4158.  
  4159.     // Perform the shift on the data
  4160.     data=register_value[D0_INDEX+(opcode&7)];
  4161.     for(int t=0;t<shift_count;++t)
  4162.     {
  4163.       if(data&msb)
  4164.         data=(data << 1) | 1;
  4165.       else
  4166.         data=(data << 1);
  4167.     }
  4168.  
  4169.     SetRegister(D0_INDEX+(opcode&7), data, size);
  4170.  
  4171.     SetConditionCodes(0, 0, data, size, OTHER, N_FLAG|Z_FLAG|C_FLAG|V_FLAG); 
  4172.     if(data&1)
  4173.       register_value[SR_INDEX] |= C_FLAG;
  4174.   }
  4175.  
  4176.   if (trace)
  4177.   {
  4178.     trace_record+="{Mnemonic {ROL";
  4179.     if(size==BYTE)
  4180.       trace_record+=".B ";
  4181.     else if(size==WORD)
  4182.       trace_record+=".W ";
  4183.     else if(size==LONG)
  4184.       trace_record+=".L ";
  4185.     trace_record+=ea_description;
  4186.     trace_record+="}} ";
  4187.   }
  4188.   return(EXECUTE_OK);
  4189. }
  4190.  
  4191. ///////////////////////////////////////////////////////////////////////////////
  4192. // Execute the 'ROR' instruction 
  4193. ///////////////////////////////////////////////////////////////////////////////
  4194. int m68000::ExecuteROR(int opcode, String& trace_record, int trace)
  4195. {
  4196.   int status, size, in_register_flag, shift_count;
  4197.   unsigned long address;
  4198.   unsigned int data;
  4199.   String ea_description;
  4200.  
  4201.   size=(opcode&0x00c0) >> 6;
  4202.  
  4203.   // Check to see if this is a memory or register rotate
  4204.   if(size == 3)
  4205.   {
  4206.     size=WORD;    // Memory always rotates a word
  4207.  
  4208.     // Get the address
  4209.     if((status=ComputeEffectiveAddress(address,in_register_flag,ea_description,
  4210.                  opcode & 0x3f, size, trace)) != EXECUTE_OK)
  4211.     { return(status); }
  4212.  
  4213.     // Fetch the data
  4214.     if((status=Peek(address, data, size)) != EXECUTE_OK)
  4215.       return(status);
  4216.  
  4217.     // Rotate the data to the right by one bit.
  4218.     if(data&1)
  4219.       data=0x8000 | (data >> 1);
  4220.     else
  4221.       data=(data >> 1) & 0x7fff;
  4222.  
  4223.     // Store the shifted data
  4224.     if((status=Poke(address, data, size)) != EXECUTE_OK)
  4225.       return(status);
  4226.  
  4227.     // Set the condition codes
  4228.     SetConditionCodes(0, 0, data, size, OTHER, N_FLAG|Z_FLAG|C_FLAG|V_FLAG); 
  4229.     if(data & 0x8000)
  4230.       register_value[SR_INDEX] |= C_FLAG;
  4231.   }
  4232.   else
  4233.   {
  4234.     // Compute the shift count
  4235.     if(opcode&32)
  4236.     {
  4237.       shift_count=register_value[D0_INDEX+((opcode&0x0e00) >> 9)] & 0x3f;
  4238.       if(trace)
  4239.         ea_description=register_data[D0_INDEX+((opcode&0x0e00) >> 9)].name;
  4240.     }
  4241.     else
  4242.     {
  4243.       if((shift_count=(opcode&0x0e00) >> 9) == 0)
  4244.         shift_count=8;
  4245.  
  4246.       if(trace)
  4247.       {
  4248.         ea_description="#$";
  4249.         ea_description+=IntToString(shift_count,1);
  4250.       }
  4251.     }
  4252.  
  4253.     if(trace)
  4254.     {
  4255.       ea_description+=",";
  4256.       ea_description+=register_data[D0_INDEX+(opcode&7)].name;
  4257.     }
  4258.  
  4259.     unsigned int msb;
  4260.  
  4261.     // Setup most sign. byte indicator
  4262.     if(size==BYTE)
  4263.       msb=0x80;
  4264.     else if(size==WORD)
  4265.       msb=0x8000;
  4266.     else
  4267.       msb=0x80000000;
  4268.  
  4269.     // Perform the shift on the data
  4270.     data=register_value[D0_INDEX+(opcode&7)];
  4271.     for(int t=0;t<shift_count;++t)
  4272.     {
  4273.       if(data&1)
  4274.         data=msb | (data >> 1);
  4275.       else
  4276.         data=(data >> 1) & ~msb;
  4277.     }
  4278.     
  4279.     SetRegister(D0_INDEX+(opcode&7), data, size);
  4280.  
  4281.     SetConditionCodes(0, 0, data, size, OTHER, N_FLAG|Z_FLAG|C_FLAG|V_FLAG); 
  4282.     if(data&msb)
  4283.       register_value[SR_INDEX] |= C_FLAG;
  4284.   }
  4285.  
  4286.   if (trace)
  4287.   {
  4288.     trace_record+="{Mnemonic {ROR";
  4289.     if(size==BYTE)
  4290.       trace_record+=".B ";
  4291.     else if(size==WORD)
  4292.       trace_record+=".W ";
  4293.     else if(size==LONG)
  4294.       trace_record+=".L ";
  4295.     trace_record+=ea_description;
  4296.     trace_record+="}} ";
  4297.   }
  4298.   return(EXECUTE_OK);
  4299. }
  4300.  
  4301. ///////////////////////////////////////////////////////////////////////////////
  4302. // Execute the 'ROXL' instruction 
  4303. ///////////////////////////////////////////////////////////////////////////////
  4304. int m68000::ExecuteROXL(int opcode, String& trace_record, int trace)
  4305. {
  4306.   int status, size, in_register_flag, shift_count;
  4307.   unsigned long address;
  4308.   unsigned int data;
  4309.   String ea_description;
  4310.  
  4311.   size=(opcode&0x00c0) >> 6;
  4312.  
  4313.   // Check to see if this is a memory or register rotate
  4314.   if(size == 3)
  4315.   {
  4316.     size=WORD;    // Memory always rotates a word
  4317.  
  4318.     // Get the address
  4319.     if((status=ComputeEffectiveAddress(address,in_register_flag,ea_description,
  4320.                  opcode & 0x3f, size, trace)) != EXECUTE_OK)
  4321.     { return(status); }
  4322.  
  4323.     // Fetch the data
  4324.     if((status=Peek(address, data, size)) != EXECUTE_OK)
  4325.       return(status);
  4326.  
  4327.     // Rotate the data to the left by one bit.
  4328.     if(register_value[SR_INDEX]&X_FLAG)
  4329.       data=(data << 1) | 0x0001;
  4330.     else
  4331.       data=(data << 1);
  4332.  
  4333.     // Store the shifted data
  4334.     if((status=Poke(address, data, size)) != EXECUTE_OK)
  4335.       return(status);
  4336.  
  4337.     SetConditionCodes(0,0,data,size,OTHER,N_FLAG|Z_FLAG|C_FLAG|X_FLAG|V_FLAG); 
  4338.     if(data&0x00010000)
  4339.     {
  4340.       register_value[SR_INDEX] |= C_FLAG;
  4341.       register_value[SR_INDEX] |= X_FLAG;
  4342.     }
  4343.   }
  4344.   else
  4345.   {
  4346.     // Compute the shift count
  4347.     if(opcode&32)
  4348.     {
  4349.       shift_count=register_value[D0_INDEX+((opcode&0x0e00) >> 9)] & 0x3f;
  4350.       if(trace)
  4351.         ea_description=register_data[D0_INDEX+((opcode&0x0e00) >> 9)].name;
  4352.     }
  4353.     else
  4354.     {
  4355.       if((shift_count=(opcode&0x0e00) >> 9) == 0)
  4356.         shift_count=8;
  4357.  
  4358.       if(trace)
  4359.       {
  4360.         ea_description="#$";
  4361.         ea_description+=IntToString(shift_count,1);
  4362.       }
  4363.     }
  4364.  
  4365.     if(trace)
  4366.     {
  4367.       ea_description+=",";
  4368.       ea_description+=register_data[D0_INDEX+(opcode&7)].name;
  4369.     }
  4370.  
  4371.     unsigned int msb, extend;
  4372.  
  4373.     // Setup msb
  4374.     if(size==BYTE)
  4375.       msb=0x80;
  4376.     else if(size==WORD)
  4377.       msb=0x8000;
  4378.     else
  4379.       msb=0x80000000;
  4380.  
  4381.     // Set extend
  4382.     extend=register_value[SR_INDEX]&X_FLAG;
  4383.  
  4384.     // Perform the shift on the data
  4385.     data=register_value[D0_INDEX+(opcode&7)];
  4386.     for(int t=0;t<shift_count;++t)
  4387.     {
  4388.       if(extend)
  4389.       {
  4390.         extend=data&msb;
  4391.         data=(data << 1) | 1;
  4392.       }
  4393.       else
  4394.       {
  4395.         extend=data&msb;
  4396.         data=(data << 1);
  4397.       }
  4398.     }
  4399.  
  4400.     SetRegister(D0_INDEX+(opcode&7), data, size);
  4401.  
  4402.     SetConditionCodes(0,0,data,size,OTHER,N_FLAG|Z_FLAG|X_FLAG|C_FLAG|V_FLAG); 
  4403.     if(extend)
  4404.     {
  4405.       register_value[SR_INDEX] |= C_FLAG;
  4406.       register_value[SR_INDEX] |= X_FLAG;
  4407.     }
  4408.   }
  4409.  
  4410.   if (trace)
  4411.   {
  4412.     trace_record+="{Mnemonic {ROXL";
  4413.     if(size==BYTE)
  4414.       trace_record+=".B ";
  4415.     else if(size==WORD)
  4416.       trace_record+=".W ";
  4417.     else if(size==LONG)
  4418.       trace_record+=".L ";
  4419.     trace_record+=ea_description;
  4420.     trace_record+="}} ";
  4421.   }
  4422.   return(EXECUTE_OK);
  4423. }
  4424.  
  4425. ///////////////////////////////////////////////////////////////////////////////
  4426. // Execute the 'ROXR' instruction 
  4427. ///////////////////////////////////////////////////////////////////////////////
  4428. int m68000::ExecuteROXR(int opcode, String& trace_record, int trace)
  4429. {
  4430.   int status, size, in_register_flag, shift_count;
  4431.   unsigned long address;
  4432.   unsigned int data;
  4433.   String ea_description;
  4434.  
  4435.   size=(opcode&0x00c0) >> 6;
  4436.  
  4437.   // Check to see if this is a memory or register rotate
  4438.   if(size == 3)
  4439.   {
  4440.     size=WORD;    // Memory always rotates a word
  4441.  
  4442.     // Get the address
  4443.     if((status=ComputeEffectiveAddress(address,in_register_flag,ea_description,
  4444.                  opcode & 0x3f, size, trace)) != EXECUTE_OK)
  4445.     { return(status); }
  4446.  
  4447.     // Fetch the data
  4448.     if((status=Peek(address, data, size)) != EXECUTE_OK)
  4449.       return(status);
  4450.  
  4451.     // Set carry flag
  4452.     int carry=data&1;
  4453.  
  4454.     // Rotate the data to the right by one bit.
  4455.     if(register_value[SR_INDEX]&X_FLAG)
  4456.       data=0x8000 | (data >> 1);
  4457.     else
  4458.       data=(data >> 1) & 0x7fff;
  4459.  
  4460.     // Store the shifted data
  4461.     if((status=Poke(address, data, size)) != EXECUTE_OK)
  4462.       return(status);
  4463.  
  4464.     // Set the condition codes
  4465.     SetConditionCodes(0,0,data,size,OTHER,N_FLAG|Z_FLAG|X_FLAG|C_FLAG|V_FLAG); 
  4466.     if(carry)
  4467.     {
  4468.       register_value[SR_INDEX] |= C_FLAG;
  4469.       register_value[SR_INDEX] |= X_FLAG;
  4470.     }
  4471.   }
  4472.   else
  4473.   {
  4474.     // Compute the shift count
  4475.     if(opcode&32)
  4476.     {
  4477.       shift_count=register_value[D0_INDEX+((opcode&0x0e00) >> 9)] & 0x3f;
  4478.       if(trace)
  4479.         ea_description=register_data[D0_INDEX+((opcode&0x0e00) >> 9)].name;
  4480.     }
  4481.     else
  4482.     {
  4483.       if((shift_count=(opcode&0x0e00) >> 9) == 0)
  4484.         shift_count=8;
  4485.  
  4486.       if(trace)
  4487.       {
  4488.         ea_description="#$";
  4489.         ea_description+=IntToString(shift_count,1);
  4490.       }
  4491.     }
  4492.  
  4493.     if(trace)
  4494.     {
  4495.       ea_description+=",";
  4496.       ea_description+=register_data[D0_INDEX+(opcode&7)].name;
  4497.     }
  4498.  
  4499.     unsigned int msb,extend;
  4500.  
  4501.     // Setup most sign. byte indicator
  4502.     if(size==BYTE)
  4503.       msb=0x80;
  4504.     else if(size==WORD)
  4505.       msb=0x8000;
  4506.     else
  4507.       msb=0x80000000;
  4508.  
  4509.     extend=register_value[SR_INDEX]&X_FLAG;
  4510.  
  4511.     // Perform the shift on the data
  4512.     data=register_value[D0_INDEX+(opcode&7)];
  4513.     for(int t=0;t<shift_count;++t)
  4514.     {
  4515.       if(extend)
  4516.       {
  4517.         extend=data&1;
  4518.         data=msb | (data >> 1);
  4519.       }
  4520.       else
  4521.       {
  4522.         extend=data&1;
  4523.         data=(data >> 1) & ~msb;
  4524.       }
  4525.     }
  4526.     
  4527.     SetRegister(D0_INDEX+(opcode&7), data, size);
  4528.  
  4529.     SetConditionCodes(0,0,data,size,OTHER,N_FLAG|Z_FLAG|X_FLAG|C_FLAG|V_FLAG); 
  4530.     if(extend)
  4531.     {
  4532.       register_value[SR_INDEX] |= C_FLAG;
  4533.       register_value[SR_INDEX] |= X_FLAG;
  4534.     }
  4535.   }
  4536.  
  4537.   if (trace)
  4538.   {
  4539.     trace_record+="{Mnemonic {ROXR";
  4540.     if(size==BYTE)
  4541.       trace_record+=".B ";
  4542.     else if(size==WORD)
  4543.       trace_record+=".W ";
  4544.     else if(size==LONG)
  4545.       trace_record+=".L ";
  4546.     trace_record+=ea_description;
  4547.     trace_record+="}} ";
  4548.   }
  4549.   return(EXECUTE_OK);
  4550. }
  4551.  
  4552. ///////////////////////////////////////////////////////////////////////////////
  4553. // Execute the 'RTE' instruction 
  4554. ///////////////////////////////////////////////////////////////////////////////
  4555. int m68000::ExecuteRTE(int opcode, String& trace_record, int trace)
  4556. {
  4557.   int status;
  4558.   unsigned int sr,pc;
  4559.  
  4560.   // Make sure we're in supervisor mode or trap
  4561.   if(!(register_value[SR_INDEX] & S_FLAG))
  4562.   {
  4563.     SetRegister(PC_INDEX, register_value[PC_INDEX]-2, LONG);
  4564.     if((status=ProcessException(8)) != EXECUTE_OK)
  4565.       return(status);
  4566.     if(trace);
  4567.       trace_record+="{Mnemonic {Privilege Violation Exception}} ";
  4568.     return(EXECUTE_PRIVILEGED_OK);
  4569.   }
  4570.  
  4571.   // Pop the SR off the stack
  4572.   if((status=Peek(register_value[SSP_INDEX], sr, WORD)) != EXECUTE_OK)
  4573.     return(status);
  4574.  
  4575.   SetRegister(SSP_INDEX, register_value[SSP_INDEX]+2, LONG);
  4576.   SetRegister(SR_INDEX, sr, WORD);
  4577.  
  4578.   // Pop the PC off the stack
  4579.   if((status=Peek(register_value[SSP_INDEX], pc, LONG)) != EXECUTE_OK)
  4580.     return(status);
  4581.  
  4582.   SetRegister(SSP_INDEX, register_value[SSP_INDEX]+4, LONG);
  4583.   SetRegister(PC_INDEX, pc, LONG);
  4584.  
  4585.   if(trace)
  4586.     trace_record+="{Mnemonic {RTE}} ";
  4587.  
  4588.   return(EXECUTE_PRIVILEGED_OK);
  4589. }
  4590.  
  4591. ///////////////////////////////////////////////////////////////////////////////
  4592. // Execute the 'RTR' instruction 
  4593. ///////////////////////////////////////////////////////////////////////////////
  4594. int m68000::ExecuteRTR(int opcode, String& trace_record, int trace)
  4595. {
  4596.   int status;
  4597.   unsigned int ccr,pc;
  4598.   int stackRegister;
  4599.  
  4600.   // Determine which stack pointer to use
  4601.   if(register_value[SR_INDEX] & S_FLAG)
  4602.     stackRegister = SSP_INDEX;
  4603.   else
  4604.     stackRegister = USP_INDEX;
  4605.  
  4606.   // Pop the CCR off the stack
  4607.   if((status = Peek(register_value[stackRegister], ccr, WORD)) != EXECUTE_OK)
  4608.     return(status);
  4609.  
  4610.   SetRegister(stackRegister, register_value[stackRegister] + 2, LONG);
  4611.   SetRegister(SR_INDEX, ccr, BYTE);
  4612.  
  4613.   // Pop the PC off the stack
  4614.   if((status = Peek(register_value[stackRegister], pc, LONG)) != EXECUTE_OK)
  4615.     return(status);
  4616.  
  4617.   SetRegister(stackRegister, register_value[stackRegister] + 4, LONG);
  4618.   SetRegister(PC_INDEX, pc, LONG);
  4619.  
  4620.   if(trace)
  4621.     trace_record += "{Mnemonic {RTR}} ";
  4622.  
  4623.   return(EXECUTE_OK);
  4624. }
  4625.  
  4626. ///////////////////////////////////////////////////////////////////////////////
  4627. // Execute the 'RTS' instruction 
  4628. ///////////////////////////////////////////////////////////////////////////////
  4629. int m68000::ExecuteRTS(int opcode, String& trace_record, int trace)
  4630. {
  4631.   int status;
  4632.   unsigned int pc;
  4633.   int stackRegister;
  4634.  
  4635.   // Determine which stack pointer to use
  4636.   if(register_value[SR_INDEX] & S_FLAG)
  4637.     stackRegister = SSP_INDEX;
  4638.   else
  4639.     stackRegister = USP_INDEX;
  4640.  
  4641.   // Pop the PC off the stack
  4642.   if((status = Peek(register_value[stackRegister], pc, LONG)) != EXECUTE_OK)
  4643.     return(status);
  4644.  
  4645.   SetRegister(stackRegister, register_value[stackRegister] + 4, LONG);
  4646.   SetRegister(PC_INDEX, pc, LONG);
  4647.  
  4648.   if(trace)
  4649.     trace_record += "{Mnemonic {RTS}} ";
  4650.  
  4651.   return(EXECUTE_OK);
  4652. }
  4653.  
  4654. ///////////////////////////////////////////////////////////////////////////////
  4655. // Execute the '' instruction 
  4656. ///////////////////////////////////////////////////////////////////////////////
  4657. int m68000::ExecuteSBCD(int opcode, String& trace_record, int trace)
  4658.   return(ExecuteInvalid(opcode, trace_record, trace));
  4659. }
  4660.  
  4661. ///////////////////////////////////////////////////////////////////////////////
  4662. // Execute the 'STOP' instruction 
  4663. ///////////////////////////////////////////////////////////////////////////////
  4664. int m68000::ExecuteSTOP(int opcode, String& trace_record, int trace)
  4665. {
  4666.   unsigned int newStatusRegister, status;
  4667.   String mnemonic;
  4668.  
  4669.   // Fetch the 16-bit immediate data
  4670.   status = Peek(register_value[PC_INDEX], newStatusRegister, WORD);
  4671.   if(status != EXECUTE_OK)
  4672.     return(status);
  4673.  
  4674.   // Increment the program counter
  4675.   SetRegister(PC_INDEX, register_value[PC_INDEX]+2, LONG);
  4676.  
  4677.   // Set the status register
  4678.   SetRegister(SR_INDEX, newStatusRegister, WORD);
  4679.  
  4680.   // Make sure the S-Bit is set
  4681.   if(!(register_value[SR_INDEX] & S_FLAG))
  4682.   {
  4683.     if((status=ProcessException(8)) != EXECUTE_OK)
  4684.       return(status);
  4685.     if(trace)
  4686.       trace_record+="{Mnemonic {Privilege Violation Exception}} ";
  4687.     return(EXECUTE_PRIVILEGED_OK);
  4688.   }
  4689.   
  4690.   // Stop the processor
  4691.   processor_state = STOP_STATE;
  4692.  
  4693.   if(trace)
  4694.   {
  4695.     trace_record += "{Mnemonic {STOP #$";
  4696.     trace_record += IntToString(newStatusRegister, 4);
  4697.     trace_record += "}} ";
  4698.   } 
  4699.   return(EXECUTE_PRIVILEGED_OK);
  4700. }
  4701.  
  4702. ///////////////////////////////////////////////////////////////////////////////
  4703. // Execute the 'BREAK' instruction 
  4704. ///////////////////////////////////////////////////////////////////////////////
  4705. int m68000::ExecuteBREAK(int opcode, String& trace_record, int trace)
  4706. {
  4707.  
  4708.   // Put the processor in our "fake" break state so the simulator will
  4709.   // stop running a program.
  4710.   processor_state = BREAK_STATE;
  4711.  
  4712.   if(trace)
  4713.     trace_record+="{Mnemonic {BREAK}} ";
  4714.  
  4715.   return(EXECUTE_OK);
  4716. }
  4717.  
  4718. ///////////////////////////////////////////////////////////////////////////////
  4719. // Execute the 'SUB' instruction 
  4720. ///////////////////////////////////////////////////////////////////////////////
  4721. int m68000::ExecuteSUB(int opcode, String& trace_record, int trace)
  4722. {
  4723.   int status, size, in_register_flag;
  4724.   unsigned long ea_address, register_number;
  4725.   unsigned int result, ea_data;
  4726.   String mnemonic, ea_description;
  4727.  
  4728.   size=(opcode&0x00c0) >> 6;
  4729.  
  4730.   // Get the <ea> data address
  4731.   if((status=ComputeEffectiveAddress(ea_address, in_register_flag,
  4732.                   ea_description, opcode & 0x3f, size, trace)) != EXECUTE_OK)
  4733.   { return(status); }
  4734.  
  4735.   // Fetch the <ea> data 
  4736.   if(in_register_flag)
  4737.     ea_data=register_value[ea_address];
  4738.   else
  4739.     if((status=Peek(ea_address, ea_data, size)) != EXECUTE_OK)
  4740.       return(status);
  4741.  
  4742.   // Get the register number
  4743.   register_number=D0_INDEX+((opcode&0x0e00) >> 9);
  4744.  
  4745.   if(trace)
  4746.   {
  4747.     mnemonic+="{Mnemonic {SUB";
  4748.     if (size==BYTE)
  4749.       mnemonic+=".B ";
  4750.     else if (size==WORD)
  4751.       mnemonic+=".W ";
  4752.     else if (size==LONG)
  4753.       mnemonic+=".L ";
  4754.   }
  4755.  
  4756.   if(opcode & 0x0100)    // <ea> - <Dn> -> <ea>
  4757.   {
  4758.     if(trace)
  4759.     {
  4760.       mnemonic+=register_data[register_number].name;
  4761.       mnemonic+=",";
  4762.       mnemonic+=ea_description;
  4763.     }
  4764.     result=ea_data-register_value[register_number];
  4765.     SetConditionCodes(register_value[register_number], ea_data, result, size,
  4766.                       SUBTRACTION, C_FLAG|V_FLAG|Z_FLAG|N_FLAG|X_FLAG);
  4767.     if((status=Poke(ea_address, result, size)) != EXECUTE_OK)
  4768.       return(status);
  4769.   }
  4770.   else                   // <Dn> - <ea> -> <Dn>
  4771.   {
  4772.     if(trace)
  4773.     {
  4774.       mnemonic+=ea_description;
  4775.       mnemonic+=",";
  4776.       mnemonic+=register_data[register_number].name;
  4777.     }
  4778.     result=register_value[register_number]-ea_data;
  4779.     SetConditionCodes(ea_data, register_value[register_number], result, size,
  4780.                       SUBTRACTION, C_FLAG|V_FLAG|Z_FLAG|N_FLAG|X_FLAG);
  4781.     SetRegister(register_number, result, size);
  4782.   }
  4783.  
  4784.   if(trace)
  4785.   {
  4786.     mnemonic+="}} ";
  4787.     trace_record+=mnemonic;
  4788.   }
  4789.   return(EXECUTE_OK);
  4790. }
  4791.  
  4792. ///////////////////////////////////////////////////////////////////////////////
  4793. // Execute the 'SUBA' instruction 
  4794. ///////////////////////////////////////////////////////////////////////////////
  4795. int m68000::ExecuteSUBA(int opcode, String& trace_record, int trace)
  4796. {
  4797.   int status, size, in_register_flag;
  4798.   unsigned long ea_address, register_number;
  4799.   unsigned int result, ea_data;
  4800.   String ea_description;
  4801.  
  4802.   if (opcode&0x0100)
  4803.     size=LONG;
  4804.   else
  4805.     size=WORD;
  4806.  
  4807.   // Get the <ea> data address
  4808.   if((status=ComputeEffectiveAddress(ea_address, in_register_flag,
  4809.                   ea_description, opcode & 0x3f, size, trace)) != EXECUTE_OK)
  4810.   { return(status); }
  4811.  
  4812.   // Fetch the <ea> data 
  4813.   if(in_register_flag)
  4814.     ea_data=register_value[ea_address];
  4815.   else
  4816.     if((status=Peek(ea_address, ea_data, size)) != EXECUTE_OK)
  4817.       return(status);
  4818.  
  4819.   ea_data=SignExtend(ea_data,size);
  4820.  
  4821.   // Get the register number
  4822.   register_number=A0_INDEX+((opcode&0x0e00) >> 9);
  4823.  
  4824.   // Adjust register_number if it's A7 and we're in supervisor mode
  4825.   if((register_number == USP_INDEX) && (register_value[SR_INDEX] & S_FLAG))
  4826.     register_number = SSP_INDEX;
  4827.  
  4828.   result=register_value[register_number]-ea_data;
  4829.   SetRegister(register_number, result, LONG);
  4830.  
  4831.   if(trace)
  4832.   {
  4833.     trace_record+="{Mnemonic {SUBA";
  4834.     if (size==WORD)
  4835.       trace_record+=".W ";
  4836.     else if (size==LONG)
  4837.       trace_record+=".L ";
  4838.     trace_record+=ea_description;
  4839.     trace_record+=",";
  4840.     trace_record+=register_data[register_number].name;
  4841.     trace_record+="}} ";
  4842.   }
  4843.   return(EXECUTE_OK);
  4844. }
  4845.  
  4846. ///////////////////////////////////////////////////////////////////////////////
  4847. // Execute the 'SUBI' instruction 
  4848. ///////////////////////////////////////////////////////////////////////////////
  4849. int m68000::ExecuteSUBI(int opcode, String& trace_record, int trace)
  4850. {
  4851.   int status, size, in_register;
  4852.   unsigned long dest_addr, src_addr;
  4853.   unsigned int result, src, dest;
  4854.   String mnemonic;
  4855.  
  4856.   size=(opcode&0x00c0) >> 6;
  4857.  
  4858.   if(trace)
  4859.   {
  4860.     mnemonic+="{Mnemonic {SUBI";
  4861.     if (size==BYTE)
  4862.       mnemonic+=".B ";
  4863.     else if (size==WORD)
  4864.       mnemonic+=".W ";
  4865.     else if (size==LONG)
  4866.       mnemonic+=".L ";
  4867.   }
  4868.  
  4869.   // Get the immediate data pointer
  4870.   if((status=ComputeEffectiveAddress(src_addr, in_register, mnemonic,
  4871.                     0x3c, size, trace)) != EXECUTE_OK)
  4872.   { return(status); }
  4873.  
  4874.   // Fetch the immediate data
  4875.   if((status=Peek(src_addr, src, size)) != EXECUTE_OK)
  4876.     return(status);
  4877.  
  4878.   if(trace)
  4879.     mnemonic+=",";
  4880.  
  4881.   // Get the destination data pointer
  4882.   if((status=ComputeEffectiveAddress(dest_addr, in_register, mnemonic,
  4883.                     opcode & 0x3f, size, trace)) != EXECUTE_OK)
  4884.   {
  4885.     return(status);
  4886.   }
  4887.  
  4888.   if(in_register)
  4889.   {
  4890.     dest=register_value[dest_addr];
  4891.     result=dest-src;
  4892.     SetConditionCodes(src,dest,result,size,
  4893.                       SUBTRACTION, C_FLAG|V_FLAG|Z_FLAG|N_FLAG|X_FLAG);
  4894.     SetRegister(dest_addr,result,size);
  4895.   } 
  4896.   else
  4897.   {
  4898.     if((status=Peek(dest_addr, dest, size)) != EXECUTE_OK)
  4899.       return(status);
  4900.     result=dest-src;
  4901.     SetConditionCodes(src,dest,result,size,
  4902.                       SUBTRACTION, C_FLAG|V_FLAG|Z_FLAG|N_FLAG|X_FLAG);
  4903.     if((status=Poke(dest_addr, result, size)) != EXECUTE_OK)
  4904.       return(status);
  4905.   }
  4906.  
  4907.   if (trace)
  4908.   {
  4909.     mnemonic+="}} ";
  4910.     trace_record+=mnemonic;
  4911.   }
  4912.   return(EXECUTE_OK);
  4913. }
  4914.  
  4915. ///////////////////////////////////////////////////////////////////////////////
  4916. // Execute the 'SUBQ' instruction 
  4917. ///////////////////////////////////////////////////////////////////////////////
  4918. int m68000::ExecuteSUBQ(int opcode, String& trace_record, int trace)
  4919. {
  4920.   int status, size, in_register_flag;
  4921.   unsigned long ea_address, immediate_data;
  4922.   unsigned int result, ea_data;
  4923.   String ea_description;
  4924.  
  4925.   size=(opcode&0x00c0) >> 6;
  4926.  
  4927.   // Get the immediate data out of the opcode
  4928.   if((immediate_data=(opcode&0x0e00) >> 9) == 0)
  4929.     immediate_data=8;
  4930.  
  4931.   // Get the <ea> data address
  4932.   if((status=ComputeEffectiveAddress(ea_address, in_register_flag,
  4933.                   ea_description, opcode & 0x3f, size, trace)) != EXECUTE_OK)
  4934.   { return(status); }
  4935.  
  4936.   // Fetch the <ea> data 
  4937.   if(in_register_flag)
  4938.     ea_data=register_value[ea_address];
  4939.   else
  4940.     if((status=Peek(ea_address, ea_data, size)) != EXECUTE_OK)
  4941.       return(status);
  4942.  
  4943.   if(in_register_flag)
  4944.   {
  4945.     result=ea_data-immediate_data;
  4946.     if((ea_address>=A0_INDEX) && (ea_address<=SSP_INDEX))
  4947.     {
  4948.       SetRegister(ea_address, result, LONG);
  4949.     }
  4950.     else
  4951.     {
  4952.       SetConditionCodes(immediate_data, ea_data, result, size,
  4953.                         SUBTRACTION, C_FLAG|V_FLAG|Z_FLAG|N_FLAG|X_FLAG);
  4954.       SetRegister(ea_address, result, size);
  4955.     }
  4956.   }
  4957.   else
  4958.   {
  4959.     result=ea_data-immediate_data;
  4960.     SetConditionCodes(immediate_data, ea_data, result, size,
  4961.                       SUBTRACTION, C_FLAG|V_FLAG|Z_FLAG|N_FLAG|X_FLAG);
  4962.     if((status=Poke(ea_address, result, size)) != EXECUTE_OK)
  4963.       return(status);
  4964.   }
  4965.  
  4966.   if(trace)
  4967.   {
  4968.     trace_record+="{Mnemonic {SUBQ";
  4969.     if (size==BYTE)
  4970.       trace_record+=".B ";
  4971.     else if (size==WORD)
  4972.       trace_record+=".W ";
  4973.     else if (size==LONG)
  4974.       trace_record+=".L ";
  4975.     trace_record+="#$";
  4976.     trace_record+=IntToString(immediate_data,1);
  4977.     trace_record+=",";
  4978.     trace_record+=ea_description;
  4979.     trace_record+="}} ";
  4980.   }
  4981.   return(EXECUTE_OK);
  4982. }
  4983.  
  4984. ///////////////////////////////////////////////////////////////////////////////
  4985. // Execute the 'SUBX' instruction 
  4986. ///////////////////////////////////////////////////////////////////////////////
  4987. int m68000::ExecuteSUBX(int opcode, String& trace_record, int trace)
  4988. {
  4989.   int status, size, in_register_flag;
  4990.   unsigned long src_address, dest_address;
  4991.   unsigned int result, src, dest;
  4992.   String mnemonic;
  4993.  
  4994.   size = (opcode & 0x00c0) >> 6;
  4995.  
  4996.   if(trace)
  4997.   {
  4998.     mnemonic += "{Mnemonic {SUBX";
  4999.     if(size == BYTE)
  5000.       mnemonic += ".B ";
  5001.     else if(size == WORD)
  5002.       mnemonic += ".W ";
  5003.     else if(size == LONG)
  5004.       mnemonic += ".L ";
  5005.   }
  5006.  
  5007.   // Get the addresses
  5008.   if(opcode & 8)
  5009.   {
  5010.     if((status = ComputeEffectiveAddress(src_address, in_register_flag,
  5011.             mnemonic, 0x20 | (opcode & 7) , size, trace)) != EXECUTE_OK)
  5012.     { return(status); }
  5013.  
  5014.     if(trace)
  5015.       mnemonic += ",";
  5016.  
  5017.     if((status = ComputeEffectiveAddress(dest_address, in_register_flag,
  5018.             mnemonic, 0x20 | ((opcode & 0x0e00) >> 9), size, trace)) != EXECUTE_OK)
  5019.     { return(status); }
  5020.  
  5021.     if((status = Peek(src_address, src, size)) != EXECUTE_OK)
  5022.       return(status);
  5023.     if((status = Peek(dest_address, dest, size)) != EXECUTE_OK)
  5024.       return(status);
  5025.   }
  5026.   else
  5027.   {
  5028.     src_address = D0_INDEX + (opcode & 0x0007);
  5029.     src = register_value[src_address];
  5030.     dest_address = D0_INDEX + ((opcode & 0x0e00) >> 9);
  5031.     dest = register_value[dest_address];
  5032.     if(trace)
  5033.     {
  5034.       mnemonic += register_data[src_address].name;
  5035.       mnemonic += ",";
  5036.       mnemonic += register_data[dest_address].name;
  5037.     }
  5038.   }
  5039.  
  5040.   if(register_value[SR_INDEX] & X_FLAG)
  5041.     result = dest - src - 1;
  5042.   else
  5043.     result = dest - src;
  5044.  
  5045.   if(size == BYTE)
  5046.     result = result & 0xff;
  5047.   else if(size == WORD)
  5048.     result = result & 0xffff;
  5049.   else if(size == LONG)
  5050.     result = result & 0xffffffff;
  5051.  
  5052.   SetConditionCodes(src, dest, result, size,
  5053.                     SUBTRACTION, C_FLAG|V_FLAG|N_FLAG|X_FLAG);
  5054.   if(result)
  5055.     register_value[SR_INDEX] &= ~Z_FLAG;
  5056.  
  5057.   if(opcode & 8)
  5058.   {
  5059.     if((status = Poke(dest_address, result, size)) != EXECUTE_OK)
  5060.       return(status);
  5061.   }
  5062.   else
  5063.   {
  5064.     SetRegister(dest_address, result, size);
  5065.   }
  5066.  
  5067.   if(trace)
  5068.   {
  5069.     mnemonic += "}} ";
  5070.     trace_record += mnemonic;
  5071.   }
  5072.   return(EXECUTE_OK);
  5073. }
  5074.  
  5075. ///////////////////////////////////////////////////////////////////////////////
  5076. // Execute the 'SWAP' instruction 
  5077. ///////////////////////////////////////////////////////////////////////////////
  5078. int m68000::ExecuteSWAP(int opcode, String& trace_record, int trace)
  5079. {
  5080.   int register_number;
  5081.   unsigned int data;
  5082.  
  5083.   register_number=D0_INDEX+(opcode&7);
  5084.   data = register_value[register_number];
  5085.   data = ((data >> 16) & 0xffff) | ((data << 16) & 0xffff0000);
  5086.   SetRegister(register_number, data, LONG);
  5087.   SetConditionCodes(0, 0, data, LONG,
  5088.                     OTHER, C_FLAG|V_FLAG|Z_FLAG|N_FLAG);
  5089.   if(trace)
  5090.   {
  5091.     trace_record+="{Mnemonic {SWAP.W ";
  5092.     trace_record+=register_data[register_number].name;
  5093.     trace_record+="}} ";
  5094.   }
  5095.   return(EXECUTE_OK);
  5096. }
  5097.  
  5098. ///////////////////////////////////////////////////////////////////////////////
  5099. // Execute the 'Scc' instruction 
  5100. ///////////////////////////////////////////////////////////////////////////////
  5101. int m68000::ExecuteScc(int opcode, String& trace_record, int trace)
  5102. {
  5103.   int status, in_register_flag;
  5104.   unsigned long address;
  5105.   unsigned int result;
  5106.   String mnemonic, ea_description;
  5107.  
  5108.   if(trace) trace_record+="{Mnemonic {S";
  5109.  
  5110.   // Get the effective address
  5111.   if((status=ComputeEffectiveAddress(address, in_register_flag, ea_description,
  5112.                     opcode & 0x3f, BYTE, trace)) != EXECUTE_OK)
  5113.   { return(status); }
  5114.  
  5115.   // Check to see if the result should be all 1's or 0's
  5116.   if(CheckConditionCodes((opcode & 0x0f00) >> 8, mnemonic, trace))
  5117.     result=0xff;
  5118.   else
  5119.     result=0;
  5120.  
  5121.   // Store the result  
  5122.   if(in_register_flag)
  5123.     SetRegister(address, result, BYTE);
  5124.   else
  5125.     if((status=Poke(address, result, BYTE)) != EXECUTE_OK)
  5126.       return(status);
  5127.  
  5128.   if(trace)
  5129.   {
  5130.     mnemonic+=".B ";
  5131.     mnemonic+=ea_description;
  5132.     mnemonic+="}} ";
  5133.     trace_record+=mnemonic;
  5134.   }
  5135.   return(EXECUTE_OK);
  5136. }
  5137.  
  5138. ///////////////////////////////////////////////////////////////////////////////
  5139. // Execute the 'TAS' instruction 
  5140. ///////////////////////////////////////////////////////////////////////////////
  5141. int m68000::ExecuteTAS(int opcode, String& trace_record, int trace)
  5142. {
  5143.   int status, in_register_flag;
  5144.   unsigned long address;
  5145.   unsigned int data;
  5146.   String ea_description;
  5147.  
  5148.   // Get the effective address
  5149.   if((status=ComputeEffectiveAddress(address, in_register_flag, ea_description,
  5150.                     opcode & 0x3f, BYTE, trace)) != EXECUTE_OK)
  5151.   { return(status); }
  5152.  
  5153.   // Fetch the data
  5154.   if(in_register_flag)
  5155.     data=register_value[address];
  5156.   else
  5157.     if((status=Peek(address, data, BYTE)) != EXECUTE_OK)
  5158.       return(status);
  5159.  
  5160.   SetConditionCodes(0, 0, data, BYTE, OTHER, C_FLAG|V_FLAG|Z_FLAG|N_FLAG);
  5161.  
  5162.   // Set the high order bit
  5163.   data |= 0x80;
  5164.  
  5165.   // Store the result  
  5166.   if(in_register_flag)
  5167.     SetRegister(address, data, BYTE);
  5168.   else
  5169.     if((status=Poke(address, data, BYTE)) != EXECUTE_OK)
  5170.       return(status);
  5171.  
  5172.   if(trace)
  5173.   {
  5174.     trace_record+="{Mnemonic {TAS.B ";
  5175.     trace_record+=ea_description;
  5176.     trace_record+="}} ";
  5177.   }
  5178.   return(EXECUTE_OK);
  5179. }
  5180.  
  5181. ///////////////////////////////////////////////////////////////////////////////
  5182. // Execute the 'TRAP' instruction
  5183. ///////////////////////////////////////////////////////////////////////////////
  5184. int m68000::ExecuteTRAP(int opcode, String& trace_record, int trace)
  5185. {
  5186.   int status;
  5187.  
  5188.   // Process the exception
  5189.   if((status=ProcessException(32+(opcode&0xf))) != EXECUTE_OK)
  5190.     return(status);
  5191.  
  5192.   if(trace)
  5193.   {
  5194.     trace_record+="{Mnemonic {TRAP #$";
  5195.     trace_record+=IntToString(32+(opcode&0xf), 1);
  5196.     trace_record+="}} ";
  5197.   } 
  5198.   return(EXECUTE_OK);
  5199. }
  5200.  
  5201. ///////////////////////////////////////////////////////////////////////////////
  5202. // Execute the 'TRAPV' instruction 
  5203. ///////////////////////////////////////////////////////////////////////////////
  5204. int m68000::ExecuteTRAPV(int opcode, String& trace_record, int trace)
  5205. {
  5206.   int status;
  5207.  
  5208.   // If the overflow bit is set then trap
  5209.   if(register_value[SR_INDEX] & V_FLAG)
  5210.   {
  5211.     // Process the exception
  5212.     if((status=ProcessException(7)) != EXECUTE_OK)
  5213.       return(status);
  5214.   }
  5215.  
  5216.   if(trace)
  5217.     trace_record+="{Mnemonic {TRAPV}} ";
  5218.  
  5219.   return(EXECUTE_OK);
  5220. }
  5221.  
  5222. ///////////////////////////////////////////////////////////////////////////////
  5223. // Execute the 'TST' instruction 
  5224. ///////////////////////////////////////////////////////////////////////////////
  5225. int m68000::ExecuteTST(int opcode, String& trace_record, int trace)
  5226. {
  5227.   int status, size, in_register_flag;
  5228.   unsigned long address;
  5229.   unsigned int data;
  5230.   String ea_description;
  5231.  
  5232.   size=((opcode&0x00c0) >> 6);
  5233.  
  5234.   // Get the effective address
  5235.   if((status=ComputeEffectiveAddress(address, in_register_flag, ea_description,
  5236.                     opcode & 0x3f, size, trace)) != EXECUTE_OK)
  5237.   { return(status); }
  5238.  
  5239.   // Fetch the data
  5240.   if(in_register_flag)
  5241.     data=register_value[address];
  5242.   else
  5243.     if((status=Peek(address, data, size)) != EXECUTE_OK)
  5244.       return(status);
  5245.  
  5246.   SetConditionCodes(0, 0, data, size, OTHER, C_FLAG|V_FLAG|Z_FLAG|N_FLAG);
  5247.  
  5248.   if(trace)
  5249.   {
  5250.     trace_record+="{Mnemonic {TST";
  5251.     if(size==BYTE)
  5252.       trace_record+=".B ";
  5253.     else if(size==WORD)
  5254.       trace_record+=".W ";
  5255.     else if(size==LONG)
  5256.       trace_record+=".L ";
  5257.     trace_record+=ea_description;
  5258.     trace_record+="}} ";
  5259.   }
  5260.   return(EXECUTE_OK);
  5261. }
  5262.  
  5263. ///////////////////////////////////////////////////////////////////////////////
  5264. // Execute the 'UNLK' instruction 
  5265. ///////////////////////////////////////////////////////////////////////////////
  5266. int m68000::ExecuteUNLK(int opcode, String& trace_record, int trace)
  5267. {
  5268.   int status, register_number, stack_index;
  5269.   unsigned int fp;
  5270.  
  5271.   // Get the address register number
  5272.   register_number=A0_INDEX+(opcode&0x0007);
  5273.  
  5274.   // Adjust register_number if it's A7 and we're in supervisor mode
  5275.   if((register_number == USP_INDEX) && (register_value[SR_INDEX] & S_FLAG))
  5276.     register_number = SSP_INDEX;
  5277.  
  5278.   // Get the stack index
  5279.   if(register_value[SR_INDEX]&S_FLAG)
  5280.     stack_index=SSP_INDEX;
  5281.   else
  5282.     stack_index=USP_INDEX;
  5283.  
  5284.   // Set the stack pointer to the frame pointer
  5285.   SetRegister(stack_index, register_value[register_number], LONG);
  5286.  
  5287.   // Pop the frame pointer from the stack
  5288.   if((status=Peek(register_value[stack_index], fp , LONG)) != EXECUTE_OK)
  5289.     { return(status); }
  5290.   SetRegister(register_number, fp, LONG);
  5291.   SetRegister(stack_index, register_value[stack_index]+4, LONG);
  5292.  
  5293.   if(trace)
  5294.   {
  5295.     trace_record+="{Mnemonic {UNLK ";
  5296.     trace_record+=register_data[register_number].name;
  5297.     trace_record+="}} ";
  5298.   }
  5299.   return(EXECUTE_OK);
  5300. }
  5301.  
  5302. ///////////////////////////////////////////////////////////////////////////////
  5303. // Execute 'Invalid' instructions 
  5304. ///////////////////////////////////////////////////////////////////////////////
  5305. int m68000::ExecuteInvalid(int opcode, String& trace_record, int trace)
  5306. {
  5307.   int status;
  5308.  
  5309.   // Move the PC back to the start of the illegal instruction opcode
  5310.   SetRegister(PC_INDEX, register_value[PC_INDEX]-2, LONG);
  5311.  
  5312.   // Process the illegal instruction exception
  5313.   if((status=ProcessException(4)) != EXECUTE_OK)
  5314.     return(status);
  5315.  
  5316.   if(trace)
  5317.     trace_record+="{Mnemonic {Illegal Instruction Exception}} ";
  5318.  
  5319.   return(EXECUTE_OK);
  5320. }
  5321.  
  5322. ///////////////////////////////////////////////////////////////////////////////
  5323. // Process an Exeception
  5324. ///////////////////////////////////////////////////////////////////////////////
  5325. int m68000::ProcessException(int vector)
  5326. {
  5327.   int status;
  5328.  
  5329.   // Copy the SR to a temp
  5330.   unsigned long sr = register_value[SR_INDEX];
  5331.  
  5332.   // Change to Supervisor mode and clear the Trace mode
  5333.   register_value[SR_INDEX] |= S_FLAG;
  5334.   register_value[SR_INDEX] &= ~T_FLAG;
  5335.  
  5336.   // Push the PC and SR onto the supervisor stack
  5337.   SetRegister(SSP_INDEX, register_value[SSP_INDEX]-4, LONG);
  5338.   if((status=Poke(register_value[SSP_INDEX],
  5339.        register_value[PC_INDEX], LONG)) != EXECUTE_OK)
  5340.   { return(status); }
  5341.  
  5342.   SetRegister(SSP_INDEX, register_value[SSP_INDEX]-2, LONG);
  5343.   if((status=Poke(register_value[SSP_INDEX], sr, WORD)) != EXECUTE_OK)
  5344.   { return(status); }
  5345.  
  5346.   // Get the service routine's address
  5347.   unsigned int service_address;
  5348.   if((status=Peek(vector*4, service_address , LONG)) != EXECUTE_OK)
  5349.     return(status); 
  5350.  
  5351.   // Change the program counter to the service routine's address
  5352.   SetRegister(PC_INDEX, service_address, LONG);
  5353.  
  5354.   return(EXECUTE_OK);
  5355. }
  5356.  
  5357. ///////////////////////////////////////////////////////////////////////////////
  5358. // Execute the Address Error Cycle
  5359. ///////////////////////////////////////////////////////////////////////////////
  5360. int m68000::ExecuteAddressError(int opcode, String& trace_record, int trace)
  5361. {
  5362.   int status;
  5363.  
  5364.   // Copy the SR to a temp
  5365.   unsigned long sr = register_value[SR_INDEX];
  5366.  
  5367.   // Change to Supervisor mode and clear the Trace mode
  5368.   register_value[SR_INDEX] |= S_FLAG;
  5369.   register_value[SR_INDEX] &= ~T_FLAG;
  5370.  
  5371.   // Push the PC
  5372.   SetRegister(SSP_INDEX, register_value[SSP_INDEX]-4, LONG);
  5373.   if((status=Poke(register_value[SSP_INDEX],
  5374.        register_value[PC_INDEX], LONG)) != EXECUTE_OK)
  5375.   { return(status); }
  5376.  
  5377.   // Push the SR (tmp)
  5378.   SetRegister(SSP_INDEX, register_value[SSP_INDEX]-2, LONG);
  5379.   if((status=Poke(register_value[SSP_INDEX], sr, WORD)) != EXECUTE_OK)
  5380.   { return(status); }
  5381.  
  5382.   // Push the Opcode Word of instruction in Error
  5383.   SetRegister(SSP_INDEX, register_value[SSP_INDEX]-2, LONG);
  5384.   if((status=Poke(register_value[SSP_INDEX], opcode, WORD)) != EXECUTE_OK)
  5385.   { return(status); }
  5386.  
  5387.   ////////////////////////////////////////////////////////////////////////
  5388.   // NOTE: The following two values are not correct!!! The correct values
  5389.   //       could be derived by adding a few variables to the CPU, but
  5390.   //       I don't have time to do it now :-)
  5391.   ////////////////////////////////////////////////////////////////////////
  5392.  
  5393.   // Push Memory Address at the Fault
  5394.   SetRegister(SSP_INDEX, register_value[SSP_INDEX]-4, LONG);
  5395.   if((status=Poke(register_value[SSP_INDEX], 0, LONG)) != EXECUTE_OK)
  5396.   { return(status); }
  5397.  
  5398.   // Push status information word
  5399.   SetRegister(SSP_INDEX, register_value[SSP_INDEX]-2, LONG);
  5400.   if((status=Poke(register_value[SSP_INDEX], 9, WORD)) != EXECUTE_OK)
  5401.   { return(status); }
  5402.  
  5403.  
  5404.   // Get the service routine's address
  5405.   unsigned int service_address;
  5406.   if((status=Peek(0x0c, service_address, LONG)) != EXECUTE_OK)
  5407.     return(status); 
  5408.  
  5409.   // Change the program counter to the service routine's address
  5410.   SetRegister(PC_INDEX, service_address, LONG);
  5411.  
  5412.   if(trace)
  5413.     trace_record+="{Mnemonic {Address Error Exception}} ";
  5414.  
  5415.   return(EXECUTE_OK);
  5416. }
  5417.  
  5418. ///////////////////////////////////////////////////////////////////////////////
  5419. // Execute the Bus Error Cycle
  5420. ///////////////////////////////////////////////////////////////////////////////
  5421. int m68000::ExecuteBusError(int opcode, String& trace_record, int trace)
  5422. {
  5423.   int status;
  5424.  
  5425.   // Copy the SR to a temp
  5426.   unsigned long sr = register_value[SR_INDEX];
  5427.  
  5428.   // Change to Supervisor mode and clear the Trace mode
  5429.   register_value[SR_INDEX] |= S_FLAG;
  5430.   register_value[SR_INDEX] &= ~T_FLAG;
  5431.  
  5432.   // Push the PC
  5433.   SetRegister(SSP_INDEX, register_value[SSP_INDEX]-4, LONG);
  5434.   if((status=Poke(register_value[SSP_INDEX],
  5435.        register_value[PC_INDEX], LONG)) != EXECUTE_OK)
  5436.   { return(status); }
  5437.  
  5438.   // Push the SR (tmp)
  5439.   SetRegister(SSP_INDEX, register_value[SSP_INDEX]-2, LONG);
  5440.   if((status=Poke(register_value[SSP_INDEX], sr, WORD)) != EXECUTE_OK)
  5441.   { return(status); }
  5442.  
  5443.   // Push the Opcode Word of instruction in Error
  5444.   SetRegister(SSP_INDEX, register_value[SSP_INDEX]-2, LONG);
  5445.   if((status=Poke(register_value[SSP_INDEX], opcode, WORD)) != EXECUTE_OK)
  5446.   { return(status); }
  5447.  
  5448.   ////////////////////////////////////////////////////////////////////////
  5449.   // NOTE: The following two values are not correct!!! The correct values
  5450.   //       could be derived by adding a few variables to the CPU, but
  5451.   //       I don't have time to do it now :-)
  5452.   ////////////////////////////////////////////////////////////////////////
  5453.  
  5454.   // Push Memory Address at the Fault
  5455.   SetRegister(SSP_INDEX, register_value[SSP_INDEX]-4, LONG);
  5456.   if((status=Poke(register_value[SSP_INDEX], 0, LONG)) != EXECUTE_OK)
  5457.   { return(status); }
  5458.  
  5459.   // Push status information word
  5460.   SetRegister(SSP_INDEX, register_value[SSP_INDEX]-2, LONG);
  5461.   if((status=Poke(register_value[SSP_INDEX], 9, WORD)) != EXECUTE_OK)
  5462.   { return(status); }
  5463.  
  5464.  
  5465.   // Get the service routine's address
  5466.   unsigned int service_address;
  5467.   if((status=Peek(0x08, service_address, LONG)) != EXECUTE_OK)
  5468.     return(status); 
  5469.  
  5470.   // Change the program counter to the service routine's address
  5471.   SetRegister(PC_INDEX, service_address, LONG);
  5472.  
  5473.   if(trace)
  5474.     trace_record+="{Mnemonic {Bus Error Exception}} ";
  5475.  
  5476.   return(EXECUTE_OK);
  5477. }
  5478.  
  5479.